线段树维护区间最大值和最小值

链接:https://ac.nowcoder.com/acm/contest/6874/D
来源:牛客网

世界第一名侦探牛牛与拥有死亡笔记的牛能互为对方的知音与最强的对手,在某次对决中,牛能给出a[1],a[2],…,a[n]n个数字,而他会对牛牛进行q次询问,每次询问的类型如下:

1:将a[x]的值改为y

2:询问[l,r]区间是否可以形成一段连续的数字。若对[l,r]区间的数字从小到大排序之后,有a[l]=a[l+1]−1=a[l+2]−2=…=a[r]−r+l,则认为该区间可以形成一段连续的数字。特别的,当l等于r时,也认为该区间可以形成一段连续的数字。

数据保证,任何时候这n个数字均互不相同。请问牛牛对每个2类型询问的答案是什么?

因为说这n个数互不相同,所以只需要判断区间里的max-min是否等于期间长度就行

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
//c(n,k)*c(m,k)*k! 
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
const int maxn=1e6+100;
int a[maxn],n,m;
int maxx=0;
int minx=0x3f3f3f3f;
struct node{
    int l,r,ma,mi;
}t[maxn];
void push_up(int p){
    t[p].ma=max(t[2*p].ma,t[2*p+1].ma);
    t[p].mi=min(t[2*p].mi,t[2*p+1].mi);
}
void build(int p,int l,int r){
    t[p].l=l;
    t[p].r=r;
    if(l==r){
        t[p].mi=a[l];
        t[p].ma=a[l];
        return ;
    }
    int mid=(l+r)/2;
    build(2*p,l,mid);
    build(2*p+1,mid+1,r);
    push_up(p);
} 
void change(int p,int x,int k){
    int L=t[p].l,R=t[p].r;
    if(L==R){
        t[p].ma=k;
        t[p].mi=k;
        return ;
    }
    int mid=(L+R)/2;
    if(x<=mid){
        change(2*p,x,k);
    }
    else{
        change(2*p+1,x,k);
    }
    push_up(p); 
}
void qmax(int p,int l,int r){
    int L=t[p].l,R=t[p].r;
    if(L>=l&&R<=r){
        maxx=max(maxx,t[p].ma);
        minx=min(minx,t[p].mi);
        return ;
    }
    int mid=(L+R)/2;
    if(l<=mid){
        qmax(2*p,l,r);
    }
    if(r>mid){
        qmax(2*p+1,l,r);
    }
    push_up(p);
}
int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
    build(1,1,n);
    int op,x,y;
    for(int i=1;i<=m;i++){
        scanf("%d%d%d",&op,&x,&y);
        if(op==1){
            change(1,x,y);
        }
        else{
            minx=0x3f3f3f3f;
            maxx=0;
            qmax(1,x,y);
            //cout<<maxx<<" "<<minx<<endl;
            if((maxx-minx+1)==(y-x+1)){
                printf("YES
");
            } 
            else{
                printf("NO
");
            }
        }
    }
}
原文地址:https://www.cnblogs.com/lipu123/p/14130874.html