题目
题目链接:
思路
数组去的情况可以写为:
a
[
1
]
,
a
[
2
]
−
a
[
1
]
,
a
[
3
]
−
a
[
2
]
+
a
[
1
]
,
a
[
4
]
−
a
[
3
]
+
a
[
2
]
−
a
[
1
]
a[1],a[2]-a[1],a[3]-a[2]+a[1],a[4]-a[3]+a[2]-a[1]
a[1],a[2]−a[1],a[3]−a[2]+a[1],a[4]−a[3]+a[2]−a[1]
可以发现,奇数下标在奇数位为正,偶数位为负
偶数下标在奇数位为负,偶数位为正
每次调换
a
[
i
]
、
a
[
i
+
1
]
a[i]、a[i+1]
a[i]、a[i+1]只用修改
a
[
i
]
、
a
[
i
+
1
]
a[i]、a[i+1]
a[i]、a[i+1]即可。
代码
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<cctype>
#include<ctime>
#include<iostream>
#include<string>
#include<map>
#include<queue>
#include<stack>
#include<set>
#include<vector>
#include<iomanip>
#include<list>
#include<bitset>
#include<sstream>
#include<fstream>
#include<complex>
#include<algorithm>
#if __cplusplus >= 201103L
#include <unordered_map>
#include <unordered_set>
#endif
#define int long long
using namespace std;
const int INF = 0x3f3f3f3f3f3f3f3f;
const int N=2e5+10;
int a[N],s[N],j[N],o[N];
struct seg{
struct sut{
int l,r,mi,mid,lazy;
}tree[N<<2];
#define ls x<<1
#define rs x<<1|1
void pp(int x){
tree[x].mi=min(tree[ls].mi,tree[rs].mi);
}
void build(int x,int l,int r,int *a){
tree[x]={l,r,INF,(l+r)>>1,0};
if(l==r){
tree[x].mi=a[l];
return;
}
build(ls,l,tree[x].mid,a);
build(rs,tree[x].mid+1,r,a);
pp(x);
}
void pd(int x){
if(tree[x].lazy){
tree[ls].lazy+=tree[x].lazy;
tree[rs].lazy+=tree[x].lazy;
tree[ls].mi+=tree[x].lazy;
tree[rs].mi+=tree[x].lazy;
tree[x].lazy=0;
}
}
int query(int x,int l,int r){
if(l<=tree[x].l&&tree[x].r<=r){
return tree[x].mi;
}
int ans=INF;
pd(x);
if(l<=tree[x].mid) ans=min(query(ls,l,r),ans);
if(r>tree[x].mid) ans=min(query(rs,l,r),ans);
pp(x);
return ans;
}
void modify(int x,int l,int r,int d){
if(l<=tree[x].l&&tree[x].r<=r){
tree[x].lazy+=d;
tree[x].mi+=d;
return;
}
pd(x);
int mid=tree[x].mid;
if(l<=mid) modify(ls,l,r,d);
if(r>mid) modify(rs,l,r,d);
pp(x);
}
} tj,to;
signed main(){
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int t;
cin>>t;
while(t--){
int n;
cin>>n;
for(int i=1;i<=n;i++){
o[i]=INF;
j[i]=INF;
}
for(int i=1;i<=n;i++){
cin>>a[i];
s[i]=a[i]-s[i-1];
if(i&1) j[i]=s[i];
else o[i]=s[i];
}
tj.build(1,1,n,j);
to.build(1,1,n,o);
int ans1=tj.query(1,1,n);
int ans2=to.query(1,1,n);//求最小值
//cout<<ans1<<" "<<ans2<<endl;
if(s[n]==0&&ans1>=0&&ans2>=0){
cout<<"YES"<<endl;
continue;
}
bool flag=0;
for(int i=1;i<=n;i++){
if(i&1){
tj.modify(1,i,n,-a[i]);
to.modify(1,i,n,a[i]);
tj.modify(1,i,n,a[i+1]);
to.modify(1,i,n,-a[i+1]);
tj.modify(1,i+1,n,-a[i]);
to.modify(1,i+1,n,a[i]);
tj.modify(1,i+1,n,a[i+1]);
to.modify(1,i+1,n,-a[i+1]);
}
else{
tj.modify(1,i,n,a[i]);
to.modify(1,i,n,-a[i]);
tj.modify(1,i,n,-a[i+1]);
to.modify(1,i,n,a[i+1]);
tj.modify(1,i+1,n,a[i]);
to.modify(1,i+1,n,-a[i]);
tj.modify(1,i+1,n,-a[i+1]);
to.modify(1,i+1,n,a[i+1]);
}
int sum;
if(n&1) sum=tj.query(1,n,n);
else sum=to.query(1,n,n);
int jj=tj.query(1,1,n);
int oo=to.query(1,1,n);
//cout<<sum<<" "<<jj<<" "<<oo<<endl;
if(sum==0&&jj>=0&&oo>=0){
flag=1;
break;
}
if(i&1){
tj.modify(1,i,n,a[i]);
to.modify(1,i,n,-a[i]);
tj.modify(1,i,n,-a[i+1]);
to.modify(1,i,n,a[i+1]);
tj.modify(1,i+1,n,a[i]);
to.modify(1,i+1,n,-a[i]);
tj.modify(1,i+1,n,-a[i+1]);
to.modify(1,i+1,n,a[i+1]);
}
else{
tj.modify(1,i,n,-a[i]);
to.modify(1,i,n,a[i]);
tj.modify(1,i,n,a[i+1]);
to.modify(1,i,n,-a[i+1]);
tj.modify(1,i+1,n,-a[i]);
to.modify(1,i+1,n,a[i]);
tj.modify(1,i+1,n,a[i+1]);
to.modify(1,i+1,n,-a[i+1]);
}
}
if(flag) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
}