分析

因为保证在任何时候数字不重复,当一个区间满足 时这个区间就是合法的。对于每个询问只需要求出区间 就可以了,用线段树维护,时间复杂度为

代码

#include<bits/stdc++.h>
using namespace std;
const int N = 4e5+100,inf = 0x3f3f3f3f;
int read() {int x;scanf("%d",&x);return x;}
int mx[N],mi[N],n,m,size;
void pushup(int u) {
    mx[u] = max(mx[u<<1],mx[u<<1|1]);
    mi[u] = min(mi[u<<1],mi[u<<1|1]);
}
void update(int u,int l,int r,int pos,int d) {
    int mid = l + r >> 1;
    if(l == r) {mx[u] = mi[u] = d;return;}
    if(pos <= mid) update(u<<1,l,mid,pos,d);
    else update(u<<1|1,mid+1,r,pos,d);
    pushup(u);
}
int ask1(int u,int l,int r,int L,int R) {
    if(l > R || r < L) return 0;
    if(L <= l && r <= R) return mx[u];
    int mid = l + r >> 1;
    return max(ask1(u<<1,l,mid,L,R),ask1(u<<1|1,mid+1,r,L,R));
}
int ask2(int u,int l,int r,int L,int R) {
    if(l > R || r < L) return inf;
    if(L <= l && r <= R) return mi[u];
    int mid = l + r >> 1;
    return min(ask2(u<<1,l,mid,L,R),ask2(u<<1|1,mid+1,r,L,R));
}
int main()
{
    n = read();m = read();
    for(int i = 1;i <= n;i++) {
        int val = read();update(1,1,n,i,val);
    }
    while(m--) {
        int opt = read(),x = read(),y = read();
        if(opt == 1) update(1,1,n,x,y);
        else {
            int R = ask1(1,1,n,x,y),L = ask2(1,1,n,x,y);
            if(R-L == y-x) puts("YES");
            else puts("NO");
        }
    }
}