CF2124E题解

前言

标记

  • qh[]:前缀和
  • ls[]:后缀和
  • .[l,r]:范围
  • |a|(a为数组):a的和

思路

  • 查找一个下标tp,满足|qh[tp]-ls[tp+1]|在此为偶数的情况下尽量小,从tp剖开成两个数组a[1,tp],b[tp+1,n]
  • 若查找不到(都为奇数)则ans=-1,若为奇数在后文k不为整数
  • 否则交换a,b满足|a|>|b|,设k=(|a|-|b|)/2;
  • 此时我们要在a序列遍历找到下标tle,满足qh[tle]>=k
  • 在tle位置剖开a成两个数组c[l,tle],d[tle+1,r]
  • 在c,d中各取出和等于k的值,共同减去
  • 如果|d|<k,则ans=-1
  • 否则此时|a|=|b|,共同减去,序列为0

代码

#include<bits/stdc++.h>
#define inf 2e9
#define int long long
using namespace std;
const int N=2e5+10;int n;
int ar[N],qh[N];
int ls(int i){
	return qh[n]-qh[i-1];
}
int ch(int i){
	return abs(qh[i]-ls(i+1));
}
int ans[18][N],idx;
void solve(){
	idx=0;
	cin>>n;
	for(int i=0;i<=17;i++){
		for(int j=1;j<=n;j++){
			ans[i][j]=0;
		}
	}
	for(int i=1;i<=n;i++) cin>>ar[i];
	for(int i=1;i<=n;i++) qh[i]=qh[i-1]+ar[i];
	if(qh[n]&1){
		cout<<"-1\n";
		return ;
	}
	int tp=-1;
	for(int i=1;i<=n;i++){
		if(ch(i)%2==0&&(tp==-1||ch(i)<ch(tp))){
			tp=i;
		}
	}//cout<<"---------------------------------------------\n";
	if(tp==-1){
		cout<<-1<<"\n";
		return ;
	}
	if(qh[tp]==ls(tp+1)){//cout<<"*";
		cout<<1<<"\n";
		for(int i=1;i<=n;i++) cout<<ar[i]<<" ";cout<<"\n";
	}
	else if(qh[tp]>ls(tp+1)){
		int k=ch(tp)/2;
		int tle;
		for(int i=1;i<=tp;i++){
			if(qh[i]>=k){
				tle=i;
				break;
			}
		}
		int sum=k;
		++idx;
		for(int i=1;i<=tle;i++){
			if(sum>=ar[i]){
				ans[idx][i]=ar[i];
				sum-=ar[i];
				ar[i]=0;
			}
			else{
				ans[idx][i]=sum;
				ar[i]-=sum;
				sum=0;
			}
		}
		sum=k;
		for(int i=tle+1;i<=tp;i++){
			if(sum>=ar[i]){
				ans[idx][i]=ar[i];
				sum-=ar[i];
				ar[i]=0;
			}
			else{
				ans[idx][i]=sum;
				ar[i]-=sum;
				sum=0;
			}
		}
		if(sum){
			cout<<-1<<"\n";
			return ;
		}
		++idx;
		for(int i=1;i<=n;i++) ans[idx][i]=ar[i];
		cout<<idx<<"\n";
		for(int i=1;i<=idx;i++){
			for(int j=1;j<=n;j++){
				cout<<ans[i][j]<<" ";
			}cout<<"\n";
		}
	}
	else{
		int k=ch(tp)/2;
		int tle;
		for(int i=tp+1;i<=n;i++){
			if(qh[i]-qh[tp]>=k){
				tle=i;
				break;
			}
		}
		int sum=k;
		++idx;
		//cout<<tp<<" "<<tle<<"\n";
		for(int i=tp+1;i<=tle;i++){
			if(sum>=ar[i]){
				ans[idx][i]=ar[i];
				sum-=ar[i];
				ar[i]=0;
			}
			else{
				ans[idx][i]=sum;
				ar[i]-=sum;
				sum=0;
			}
		}
		sum=k;
		for(int i=tle+1;i<=n;i++){
			if(sum>=ar[i]){
				ans[idx][i]=ar[i];
				sum-=ar[i];
				ar[i]=0;
			}
			else{
				ans[idx][i]=sum;
				ar[i]-=sum;
				sum=0;
			}
		}		
		if(sum){
			cout<<-1<<"\n";
			return ;
		}
		++idx;
		for(int i=1;i<=n;i++) ans[idx][i]=ar[i];
		cout<<idx<<"\n";
		for(int i=1;i<=idx;i++){
			for(int j=1;j<=n;j++){
				cout<<ans[i][j]<<" ";
			}cout<<"\n";
		}
	}//cout<<"_____________________________________________________________\n";
}
signed main(){
	int t;cin>>t;
	while(t--) solve();
	return 0;
}
posted @ 2025-07-07 15:06  Ming3398  阅读(42)  评论(0)    收藏  举报