https://codeforces.com/contest/1474/problem/D
先考虑不能变的情况,由于a[1]要被删光,那么一定是a[1]-=a[1],a[2]-=a[1],依次类推b[i]=a[i]-b[i-1],能消除的充要条件是所有b[i]>=0且b[n]=0
然后我们考虑枚举每一个相邻位置看可不可行,我们发现相邻位置变化对于奇数i的b[i]和偶数i的b[i]的改变是一样的
那么就只要看一下1-i-1这段b[i]是不是都大于0,再看看i-n这段区间的奇数小标的最小值和偶数下标的最小值变化后是否是>=0的,然后再看看b[n]的变化是否会变成0就可以了
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxl=3e5+10;
int n,m,k,cnt,tot,cas,ans;
ll a[maxl],b[maxl];
ll mi[21][2][maxl];
bool vis[maxl];
char s[maxl];
inline void prework()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
b[i]=a[i]-b[i-1];
}
for(int i=1;i<=n;i++)
mi[0][i&1][i]=mi[0][i&1][i-1]=mi[0][i&1][i+1]=b[i];
for(int k=1;k<=20;k++)
for(int d=0;d<=1;d++)
for(int i=1;i<=n;i++)
mi[k][d][i]=min(mi[k-1][d][i],mi[k-1][d][i+(1<<(k-1))]);
}
inline ll getmi(int l,int r,int d)
{
int k=log2(r-l+1);
return min(mi[k][d][l],mi[k][d][r-(1<<k)+1]);
}
inline void mainwork()
{
ans=0;
if(getmi(1,n,0)>=0 && getmi(1,n,1)>=0 && b[n]==0)
{
ans=1;
return;
}
for(int i=1;i<=n-1;i++)
{
bool flag=true;
if(i-1>0 && getmi(1,i-1,(i-1)&1)<0)
flag=false;
if(i-2>0 && getmi(1,i-2,(i-2)&1)<0)
flag=false;
if(b[i]-a[i]+a[i+1]<0)
flag=false;
if(i+2<=n && getmi(i+2,n,i&1)+2*a[i+1]-2*a[i]<0)
flag=false;
if(getmi(i+1,n,(i+1)&1)+2*a[i]-2*a[i+1]<0)
flag=false;
if((i&1)==(n&1) && b[n]+2*a[i+1]-2*a[i]!=0)
flag=false;
if((i&1)!=(n&1) && b[n]+2*a[i]-2*a[i+1]!=0)
flag=false;
if(flag)
{
ans=1;
return;
}
}
}
inline void print()
{
puts(ans?"YES":"NO");
}
int main()
{
int t=1;
scanf("%d",&t);
for(cas=1;cas<=t;cas++)
{
prework();
mainwork();
print();
}
return 0;
}