• 牛客月赛 巅峰对决(线段树)


    题目描述 

    世界第一名侦探牛牛与拥有死亡笔记的牛能互为对方的知音与最强的对手,在某次对决中,牛能给出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,q,其中n,q<=1e5

    接下来一行输入n个正整数a[i],a[i]1e9。

    接下来q行,每行第一个数字op表示询问类型.

    op1,输入正整数xy

    op2,输入正整数lr 

    输出描述:

    输出牛牛对每个2类型询问的答案,若该区间可以形成一段连续的数字输出YES,否则输出NO。

    示例1
    输入

    5 3
    2 5 4 3 1
    2 1 5
    1 1 8
    2 1 5

    输出

    YES
    NO

    思路

    题目大意是对于某一段查找区间,排序之后能成为公差为1的一段区间则输出YES。否则输出NO,其中有单点更新操作。

    考虑使用线段树维护区间内最大数与最小数,由于数字保证不同,当区间长度等于区间内最大数-区间内最小数时,为满足条件。

    #include<bits/stdc++.h>
    using namespace std;
    
    int a[100005];
    int Max[1000005*2+2];
    int Min[1000005*2+2];
    void build_tree(int left,int right,int node){
        if(left==right){
            Max[node]=a[right];
            Min[node]=a[right];
            return;
        }
        int mid=(left+right)/2;
        int left_node=node*2+1;
        int right_node=node*2+2;
        build_tree(left,mid,left_node);
        build_tree(mid+1,right,right_node);
        Max[node]=max(Max[left_node],Max[right_node]);
        Min[node]=min(Min[left_node],Min[right_node]);
    }
    void update_tree(int left,int right,int node,int idx,int val){
        if(left==right){
            Max[node]=val;
            Min[node]=val;
            return ;
        }
        int mid=(left+right)/2;
        int left_node=node*2+1;
        int right_node=node*2+2;
        if(idx>=left&&idx<=mid){
            update_tree(left,mid,left_node,idx,val);
        }
        else{
            update_tree(mid+1,right,right_node,idx,val);
        }
        Max[node]=max(Max[left_node],Max[right_node]);
        Min[node]=min(Min[left_node],Min[right_node]);
    }
    int maxx,minn;
    void query_tree(int left,int right,int node,int L,int R){
        if(R<left||L>right){
            return ;
        }
        if(L<=left&&R>=right||left==right){///这里要注意是查询区间的范围大于当前区间
            maxx=max(Max[node],maxx);
            minn=min(Min[node],minn);
            return ;
        }
        int mid=(left+right)/2;
        int left_node=node*2+1;
        int right_node=node*2+2;
        query_tree(left,mid,left_node,L,R);
        query_tree(mid+1,right,right_node,L,R);
    }
    int main(){
        int n,q,op,x,y,l,r;
        cin>>n>>q;
        for(int i=0;i<n;i++){
            scanf("%d",&a[i]);
        }
        build_tree(0,n-1,0);///建树
        /*for(int i=0;i<9;i++){
            cout<<"Max="<<" "<<Max[i]<<endl;
            cout<<"Min="<<" "<<Min[i]<<endl;
        }*/
        for(int i=0;i<q;i++){
            cin>>op;
            if(op==1){
                cin>>x>>y;
                update_tree(0,n-1,0,x-1,y);
            }
            if(op==2){
                cin>>l>>r;
                minn=2e9;maxx=0;
                query_tree(0,n-1,0,l-1,r-1);
                if(maxx-minn==r-l){cout<<"YES"<<endl;}
                else cout<<"NO"<<endl;
            }
        }
        return 0;
    }
  • 相关阅读:
    python day6 面向对象
    搭建简单的Habernate环境(一)
    Team Services 自动化部署项目
    Java 反射机制
    Java io 操作
    基于Socket的Winform例子
    在.NetCore2.0中使用Swagger
    [Python]mysql-python 安装错误 fatal error C1083: Cannot open include file: 'config-win.h': No such file or directory
    [Python]Python入坑小项目推荐- Flask example minitwit
    [linux]服务器apache配置vhost
  • 原文地址:https://www.cnblogs.com/mohari/p/13549590.html
Copyright © 2020-2023  润新知