zoukankan      html  css  js  c++  java
  • 线段树维护区间最大值和最小值

    链接: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
    ");
                }
            }
        }
    }
  • 相关阅读:
    Traefik-v2.x快速入门
    jenkins pipeline持续集成
    phpstorm 2017激活码(方法)
    PHP保留两位小数的几种方法
    php 数组排序 按照某字段
    sql大全
    解决jpgraph在php7.0版本下时,无法显示例子图表的问题
    Linux 定时任务crontab使用
    VIM命令操作
    wampserver变橙色,apache 服务无法启动!问题解决小记(安装失败亦可参考)
  • 原文地址:https://www.cnblogs.com/lipu123/p/14130874.html
Copyright © 2011-2022 走看看