题意:
问能不能通过操作多次将长度为3~5的区间都加1得到给定的数列
思路:
利用差分数组的思想,将区间X,Y都加1可以变成在X处加1,在Y+1处减1,这样我们可以通过拿这一项减前一项得到给定数列的差分数组,因为每个区间长度至少要是3,所以在每个大于0的位置,找它加3位置后面是否有足够的负数与其对应,一旦出现有数不能变成0,就肯定不能形成
#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <string>
#include <cstring>
#include <algorithm>
using namespace std;
#define ll long long
#define max_ 100010
#define mod 1000000007
#define inf 0x3f3f3f3f
int casnum=1;
int n;
ll num[200010];
ll ans[200010];
int main(int argc, char const *argv[]) {
int t;
scanf("%d",&t);
while(t--)
{
memset(num,0,sizeof num);
memset(ans,0,sizeof ans);
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%lld",&num[i]);
}
ans[n+1]=-num[n];
for(int i=n;i>=1;i--)
{
ans[i]=num[i]-num[i-1];
}
ll sum=ans[1]+ans[2]+ans[3];
int f=1;
int j=1;
for(int i=1;i<=n+1;i++)
{
if(ans[i]>0)
{
j=max(j,i+3);
while(j<=n+1)
{
if(ans[j]<0)
{
if(ans[i]>=abs(ans[j]))
{
ans[i]+=ans[j];
ans[j]=0;
}
else
{
ans[j]+=ans[i];
ans[i]=0;
}
}
if(ans[i]==0)
break;
else
j++;
}
}
if(ans[i]!=0)
{
f=0;
break;
}
}
if(f)
printf("Case #%d: Yes\n",casnum++ );
else
printf("Case #%d: No\n",casnum++ );
}
return 0;
}