前言
标记
- 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;
}