zoukankan      html  css  js  c++  java
  • P2617 Dynamic Rankings(带修主席树)

    所谓带修主席树,就是用树状数组的方法维护主席树的前缀和

    思路

    带修主席树的板子

    注意数据范围显然要离散化即可

    代码

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    struct Node{
        int sz,lson,rson;
    }PT[100100*400];
    struct Q{
        char c;
        int l,r,x,val;
    }opt[100100];
    const int MAXV = 1e9+10;
    int Nodecnt,lcnt,rcnt,root[100100],n,m,a[100100],num[200100],nx;
    int lroot[100100],rroot[100100];
    int lowbit(int x){
        return x&(-x);
    }
    void update(int L,int R,int &o,int c,int x){
        PT[++Nodecnt]=PT[o];
        o=Nodecnt;
        PT[o].sz+=c;
        if(L==R)
            return;
        int mid=(L+R)>>1;
        if(x<=mid)
            update(L,mid,PT[o].lson,c,x);
        else
            update(mid+1,R,PT[o].rson,c,x);
    }
    int query(int l,int r,int L,int R,int k){
        lcnt=0,rcnt=0;
        for(int i=L-1;i;i-=lowbit(i))
            lroot[++lcnt]=root[i];
        for(int i=R;i;i-=lowbit(i))
            rroot[++rcnt]=root[i];
        while(l<=r){
            if(l==r)
                return l;
            int lch=0,mid=(l+r)>>1;
            for(int i=1;i<=rcnt;i++)
                lch+=PT[PT[rroot[i]].lson].sz;
            for(int i=1;i<=lcnt;i++)
                lch-=PT[PT[lroot[i]].lson].sz;
            if(k>lch){//to right
                for(int i=1;i<=rcnt;i++)
                    rroot[i]=PT[rroot[i]].rson;
                for(int i=1;i<=lcnt;i++)
                    lroot[i]=PT[lroot[i]].rson;
                k-=lch;
                l=mid+1;
            }
            else{
                for(int i=1;i<=rcnt;i++)
                    rroot[i]=PT[rroot[i]].lson;
                for(int i=1;i<=lcnt;i++)
                    lroot[i]=PT[lroot[i]].lson;
                r=mid;
            }
        }
    }
    void set(int pos,int x,int c){//x-c
        while(pos<=n){
            update(1,nx,root[pos],c,x);
            pos+=lowbit(pos);
        }
    }
    int main(){
        scanf("%d %d",&n,&m);
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            num[++nx]=a[i];
        }
        for(int i=1;i<=m;i++){
            char c=getchar();
            while(c!='Q'&&c!='C')
                c=getchar();
            if(c=='Q'){
                opt[i].c='Q';
                scanf("%d %d %d",&opt[i].l,&opt[i].r,&opt[i].val);
            }
            else{
                opt[i].c='C';
                scanf("%d %d",&opt[i].val,&opt[i].x);
                num[++nx]=opt[i].x;
            }
        }
        sort(num+1,num+nx+1);
        nx=unique(num+1,num+nx+1)-num-1;
        for(int i=1;i<=n;i++)
            a[i]=lower_bound(num+1,num+nx+1,a[i])-num;
        for(int i=1;i<=m;i++)
            if(opt[i].c=='C')
                opt[i].x=lower_bound(num+1,num+nx+1,opt[i].x)-num;
        for(int i=1;i<=n;i++)
            set(i,a[i],1);
        for(int i=1;i<=m;i++){
            if(opt[i].c=='Q'){
                printf("%d
    ",num[query(1,nx,opt[i].l,opt[i].r,opt[i].val)]);
            }
            else{
                set(opt[i].val,a[opt[i].val],-1);
                set(opt[i].val,opt[i].x,1);
                a[opt[i].val]=opt[i].x;
            }
        }
        return 0;
    }
    
  • 相关阅读:
    cocos2d tiledmap
    cocos2d 例子编辑器
    cocos2d 粒子系统
    【leetcode】矩阵中的幸运数
    【leetcode】魔术索引
    【leetcode】多数元素
    【leetcode】整理字符串
    【leetcode】通过翻转子数组使两个数组相等
    【leetcode】珠玑妙算
    【leetcode】距离顺序排列矩阵单元格
  • 原文地址:https://www.cnblogs.com/dreagonm/p/10105213.html
Copyright © 2011-2022 走看看