CSUST 递增数组2 题解(思维+分段考虑)
题目链接
题目思路
这个题目其实就是本来就是严格单调上升的,这是关键条件
那么对于\(a[i]=a[i]-i\),题目转化为是否有\(a[i]\)为\(0\)
并且这个数组也是非严格单调上升
其实就是对于每次给一个区间加一段值,那么会打断这个区间的非严格单调上升性
但其实可以把他变为几个非严格单调上升的区间
每次最多增加2个区间
时间复杂度差不多\(O(500*500*log10^7)\)
代码
#include<bits/stdc++.h>
#define fi first
#define se second
#define debug cout<<"I AM HERE"<<endl;
using namespace std;
typedef long long ll;
const int maxn=1e7+5,inf=0x3f3f3f3f,mod=1e9+7;
const double eps=1e-6;
int n,k;
int a[maxn];
struct node{
int l,r;
int add;
};
vector<node> temp;
vector<node> vec;
signed main(){
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
a[i]=a[i]-i;
}
vec.push_back({1,n,0});
for(int i=1,l,r,c;i<=k;i++){
scanf("%d%d%d",&l,&r,&c);
for(int j=0;j<vec.size();j++){
node now=vec[j];
node x,y,z;
x=now;
if(x.l>x.r) continue;
if(l<=x.l&&x.r<=r){
x.add+=c;
}else if(x.l<=l&&r<=x.r){
x.r=l-1;
y.add=x.add+c;
y.l=l;
y.r=r;
z.l=r+1;
z.r=now.r;
z.add=now.add;
if(z.r>=z.l){
temp.push_back(z);
}
if(y.r>=y.l){
temp.push_back(y);
}
}else if(x.r>=l&&x.l<l){
x.r=l-1;
y.add=x.add+c;
y.l=l ;
y.r=now.r;
if(y.r>=y.l){
temp.push_back(y);
}
}else if(x.r>r&&x.l<=r){
x.r=r;
x.add+=c;
y.l=r+1;
y.r=now.r;
y.add=now.add;
if(y.r>=y.l){
temp.push_back(y);
}
}
vec[j]=x;
}
for(auto x:temp){
vec.push_back(x);
}
temp.clear();
bool flag=0;
for(auto x:vec){
if(x.l>x.r) continue;
int cha=-x.add;
if(a[x.r]<cha||a[x.l]>cha) continue;
int big=*lower_bound(a+1+x.l-1,a+1+x.r,cha);
if(big==cha){
flag=1;
break;
}
}
printf(flag?"YES\n":"NO\n");
}
return 0;
}
不摆烂了,写题