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;
}


posted @ 2021-09-14 21:31  hunxuewangzi  阅读(30)  评论(0编辑  收藏  举报