• loj #106. 二逼平衡树


    #106. 二逼平衡树

    内存限制:512 MiB时间限制:4000 ms标准输入输出
    题目类型:传统评测方式:文本比较
     题目描述

    这是一道模板题。

    您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:

    1. 查询 x  在区间内的排名;
    2. 查询区间内排名为 k 的值;
    3. 修改某一位置上的数值;
    4. 查询 x 在区间内的前趋(前趋定义为小于 x,且最大的数);
    5. 查询 x 在区间内的后继(后继定义为大于 x ,且最小的数)。

    输入格式

    第一行两个数 n,m,表示长度为 n 的有序序列和 m 个操作。
    第二行有 n个数,表示有序序列。

    下面有 m行,每行第一个数表示操作类型:

    1. 之后有三个数 l,r,x表示查询 x 在区间 [l,r]的排名;
    2. 之后有三个数 l,r,k 表示查询区间 [l,r] 内排名为 k 的数;
    3. 之后有两个数 pos,x表示将 pos位置的数修改为 x
    4. 之后有三个数 l,r,x 表示查询区间 [l,r]内 x的前趋;
    5. 之后有三个数 l,r,x 表示查询区间 [l,r] 内 x的后继.

    输出格式

    对于操作 1,2,4,5各输出一行,表示查询结果。

    样例

    样例输入

    9 6
    4 2 2 1 9 4 0 1 1
    2 1 4 3
    3 4 10
    2 1 4 3
    1 2 5 9
    4 3 9 5
    5 2 8 5

    样例输出

    2
    4
    3
    4
    9

    数据范围与提示

    1≤n,m≤5e4  −1e8≤k,x≤1e8

    #include <bits/stdc++.h>
    #define pt ch[ch[root][1]][0]
    const int MAXN=1e5+10;
    const int inf=1e8+10;
    using namespace std;
    int n;
    int ch[MAXN<<7][2],size[MAXN<<7],pre[MAXN<<7],key[MAXN<<7],cnt2=0,psize;
    int rt[MAXN],a[MAXN];
    vector<int>vec;
    void Treavel(int x)
    {
        if(x)
        {
            Treavel(ch[x][0]);
            printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size=%2d,key=%2d
    ",x,ch[x][0],ch[x][1],pre[x],size[x],key[x]);
            Treavel(ch[x][1]);
        }
    }
    void debug(int rp)
    {
        printf("root:%d
    ",rp);
        Treavel(rp);
    }
    typedef struct node{
        int root,maxx;
        void newnode(int &x,int fa,int vul){
            x=++cnt2;ch[x][0]=ch[x][1]=0;pre[x]=fa;key[x]=vul;
            size[x]=1;
        }
        void inte(){
            root=0;
            newnode(root,0,-inf);
            newnode(ch[root][1],root,inf);
        }
        void up(int x){size[x]=size[ch[x][0]]+size[ch[x][1]]+1;}
        void rotate(int x,int kind){
            int y=pre[x];
            ch[y][!kind]=ch[x][kind];pre[ch[x][kind]]=y;
            if(pre[y]) ch[pre[y]][ch[pre[y]][1]==y]=x;
            pre[x]=pre[y];ch[x][kind]=y;pre[y]=x;
            up(y);
        }
        void splay(int x,int goal){
            while(pre[x]!=goal){
                if(pre[pre[x]]==goal) rotate(x,ch[pre[x]][0]==x);
                else{
                    int y=pre[x];int kind=ch[pre[y]][0]==y;
                    if(ch[y][kind]==x) rotate(x,!kind),rotate(x,kind);
                    else rotate(y,kind),rotate(x,kind);
                }
            }
            if(goal==0) root=x;
            up(x);
        }
        void insert(int &x,int vul,int fa){
            if(!x){newnode(x,fa,vul);return ;}
            if(key[x]>vul) insert(ch[x][0],vul,x);
            else insert(ch[x][1],vul,x);
            up(x);
        }
        int find1(int x,int vul){
            if(key[x]==vul) return x;
            else if(key[x]<vul) return find1(ch[x][1],vul);
            else return find1(ch[x][0],vul);
        }
        int find2(int x,int siz){
            if(siz==size[ch[x][0]]+1) return x;
            else if(siz<=size[ch[x][0]]) return find2(ch[x][0],siz);
            else return find2(ch[x][1],siz-size[ch[x][0]]-1);
        }
        void erase(int vul){
            splay(find1(root,vul),0);
            int t=size[ch[root][0]]+1;
            splay(find2(root,t-1),0);
            splay(find2(root,t+1),root);
            pre[ch[ch[root][1]][0]]=0;ch[ch[root][1]][0]=0;up(ch[root][1]);up(root);
        }
        void pre_vul(int x,int vul){
            if(!x) return ;
            if(key[x]>=vul) pre_vul(ch[x][0],vul);
            else{
                if(vul-key[x]<=vul-maxx) maxx=key[x],pre_vul(ch[x][1],vul);
                else pre_vul(ch[x][1],vul);
            }
        }
        void last_vul(int x,int vul){
            if(!x) return ;
            if(key[x]<=vul) last_vul(ch[x][1],vul);
            else{
                if(key[x]-vul<=maxx-vul) maxx=key[x],last_vul(ch[x][0],vul);
                else last_vul(ch[x][0],vul);
            }
        }
    }node;
    typedef struct wjy{
       int l,r,sum;
    }wjy;
    wjy dd[MAXN<<7];int cnt1=0;
    typedef struct List{
        node T;
    }List;
    List d[MAXN<<2];
    void built(int &x,int y,int l,int r,int vul,int flag){
        x=++cnt1;dd[x]=dd[y];dd[x].sum+=flag;
        if(l==r) return ;
        int mid=(l+r)>>1;
        if(vul<=mid) built(dd[x].l,dd[y].l,l,mid,vul,flag);
        else built(dd[x].r,dd[y].r,mid+1,r,vul,flag);
    }
    int ans;
    vector<int>vv1;
    vector<int>vv2;
    int get_id(int x){return x&(-x);}
    void slove(int l,int r){
        for(int i=l-1;i>0;i-=get_id(i)) vv2.push_back(rt[i]);
        for(int i=r;i>0;i-=get_id(i)) vv1.push_back(rt[i]);
    }
    int querty1(int l,int r,int ql,int qr,int vul){
        slove(ql,qr);
        while(l<r){
            int mid=(l+r)>>1;
            if(mid<=vul){
                l=mid+1;
                for(int i=0;i<vv1.size();i++) ans+=dd[dd[vv1[i]].l].sum;
                for(int i=0;i<vv2.size();i++) ans-=dd[dd[vv2[i]].l].sum;
                for(int i=0;i<vv1.size();i++) vv1[i]=dd[vv1[i]].r;
                for(int i=0;i<vv2.size();i++) vv2[i]=dd[vv2[i]].r;
            }
            else{
                r=mid;
                for(int i=0;i<vv1.size();i++) vv1[i]=dd[vv1[i]].l;
                for(int i=0;i<vv2.size();i++) vv2[i]=dd[vv2[i]].l;
            }
    
        }
        return ans;
    }
    int querty2(int l,int r,int ql,int qr,int k){
        slove(ql,qr);
        int t;
        while(l<r){
            int mid=(l+r)>>1;t=0;
            for(int i=0;i<vv1.size();i++) t+=dd[dd[vv1[i]].l].sum;
            for(int i=0;i<vv2.size();i++) t-=dd[dd[vv2[i]].l].sum;
            if(t>=k){
                r=mid;
                for(int i=0;i<vv1.size();i++) vv1[i]=dd[vv1[i]].l;
                for(int i=0;i<vv2.size();i++) vv2[i]=dd[vv2[i]].l;
            }
            else{
                l=mid+1;k-=t;
                for(int i=0;i<vv1.size();i++) vv1[i]=dd[vv1[i]].r;
                for(int i=0;i<vv2.size();i++) vv2[i]=dd[vv2[i]].r;
            }
    
        }
        return l;
    }
    void update1(int root,int l,int r,int vul,int t,int flag){
        //cout<<l<<" "<<r<<endl;
        //cout<<d[root].T.root<<endl;
        if(flag) d[root].T.insert(d[root].T.root,vul,0);
        else d[root].T.erase(vul);
        //if(!flag) debug(d[root].T.root);
        if(l==r)   return ;
        int mid=(l+r)>>1;
        if(t<=mid) update1(root<<1,l,mid,vul,t,flag);
        else update1(root<<1|1,mid+1,r,vul,t,flag);
    }
    int maxn;
    void querty(int root,int l,int r,int ql,int qr,int x,int flag){
        if(ql<=l&&r<=qr){
            if(flag) d[root].T.maxx=-1*inf,d[root].T.pre_vul(d[root].T.root,x),maxn=max(maxn,d[root].T.maxx);
            else d[root].T.maxx=inf,d[root].T.last_vul(d[root].T.root,x),maxn=min(maxn,d[root].T.maxx);
            return ;
        }
        int mid=(l+r)>>1;
        if(ql<=mid) querty(root<<1,l,mid,ql,qr,x,flag);
        if(qr>mid) querty(root<<1|1,mid+1,r,ql,qr,x,flag);
    }
    void inte(){
        for(int i=1;i<=(n<<2);i++) d[i].T.inte();
        for(int i=1;i<=n;i++){
            for(int j=i;j<=n;j+=get_id(j)){
                built(rt[j],rt[j],1,psize,a[i],1);
    
            }
            update1(1,1,n,a[i],i,1);
        }
    }
    void update(int pos,int x,int y){
        for(int j=pos;j<=n;j+=get_id(j)){
            built(rt[j],rt[j],1,psize,x,-1);
            built(rt[j],rt[j],1,psize,y,1);
        }
        update1(1,1,n,x,pos,0);
        //cout<<"sb"<<endl;
        update1(1,1,n,y,pos,1);
        //cout<<"sb"<<endl;
    }
    int slove1(int l,int r,int x){
        ans=0;
        int ans1=querty1(1,psize,l,r,x-1);
        vv1.clear();vv2.clear();
        return ans1+1;
    }
    int slove2(int l,int r,int k){
        ans=querty2(1,psize,l,r,k);
        vv1.clear();vv2.clear();
        return ans;
    }
    int slove3(int l,int r,int x){
        maxn=-1*inf;querty(1,1,n,l,r,x,1);
        return maxn;
    }
    int slove4(int l,int r,int x){
        //cout<<l<<" "<<r<<endl;
        maxn=inf;querty(1,1,n,l,r,x,0);
        return maxn;
    }
    typedef struct P{
      int op,l,r,x;
    }P;
    P p[MAXN];
    int main(){
        int m;scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]),vec.push_back(a[i]);
        for(int i=1;i<=m;i++){
            scanf("%d",&p[i].op);
            if(p[i].op==3) scanf("%d%d",&p[i].l,&p[i].x),vec.push_back(p[i].x);
            else if(p[i].op==2) scanf("%d%d%d",&p[i].l,&p[i].r,&p[i].x);
            else scanf("%d%d%d",&p[i].l,&p[i].r,&p[i].x),vec.push_back(p[i].x);
        }
        sort(vec.begin(),vec.end());
        psize=unique(vec.begin(),vec.end())-vec.begin();
        for(int i=1;i<=n;i++) a[i]=lower_bound(vec.begin(),vec.begin()+psize,a[i])-vec.begin()+1;
        inte();
        for(int i=1;i<=m;i++){
            if(p[i].op==2) continue;
            p[i].x=lower_bound(vec.begin(),vec.begin()+psize,p[i].x)-vec.begin()+1;
        }
        for(int i=1;i<=m;i++){
            if(p[i].op==1) printf("%d
    ",slove1(p[i].l,p[i].r,p[i].x));
            else if(p[i].op==2) printf("%d
    ",vec[slove2(p[i].l,p[i].r,p[i].x)-1]);
            else if(p[i].op==3) update(p[i].l,a[p[i].l],p[i].x),a[p[i].l]=p[i].x;
            else if(p[i].op==4) printf("%d
    ",vec[slove3(p[i].l,p[i].r,p[i].x)-1]);
            else printf("%d
    ",vec[slove4(p[i].l,p[i].r,p[i].x)-1]);
        }
        return 0;
    }
    

      

  • 相关阅读:
    腾讯大数据开发实习面经
    网易游戏2021暑期实习生 游戏运营管理面经 已拿offer
    猿辅导大数据校招1面+2面面经
    虎牙直播内容运营(英雄联盟)三轮超高质量面经分享
    字节跳动日常实习广告大数据研发实习面经(初面)
    运营小白超详细三轮面试拿到字节跳动offer
    字节跳动前端日常实习三轮技术面经
    360大数据开发实习面经
    美团大数据开发工程师校招面经
    高级运维工程师的打怪升级之路
  • 原文地址:https://www.cnblogs.com/wang9897/p/8708163.html
Copyright © 2020-2023  润新知