CF1442A Extreme Subtraction
给出一个数列\(a_i\),每次可以将一段前缀或一段后缀减一,问是否可以变成全\(0\)。
\(n\le 3*10^4\)
显然这相当于将\(a_i\)拆成\(x_i+y_i\),满足\(x_i\)不递减,\(y_i\)不递增。
从后往前钦定\(x_i\)的值,记变量\(pre\)表示当前钦定到的最小值,初值为无限大。如果\(a_i<pre\)则\(a_i\)替换\(pre\);否则将\(a_i\)调整为\(pre\),并且将\([1,i]\)区间同时减\(a_i-pre\)。按照这个策略,如果不出现负数就合法。
这个策略让当前\(x_i\)最大,并且\(y_i\)最小,给后面的区间预留了更多的空间,所以是对的。
using namespace std;
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 30005
#define INF 1000000
#define ll long long
int n;
int a[N];
int main(){
// freopen("in.txt","r",stdin);
int T;
scanf("%d",&T);
while (T--){
scanf("%d",&n);
for (int i=1;i<=n;++i)
scanf("%d",&a[i]);
if (n==1){
printf("YES\n");
continue;
}
int pre=INF,cut=0;
bool bz=1;
for (int i=n;i>=1 && bz;--i){
a[i]-=cut;
if (a[i]<0)
bz=0;
if (a[i]<=pre)
pre=a[i];
else{
cut+=a[i]-pre;
a[i]=pre;
}
}
if (bz)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}