zoukankan      html  css  js  c++  java
  • zoj2112 Dynamic Rankings 动态区间第k大,树状数组套平衡树

     
    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #define REP(i,a,b) for(int i=a;i<=b;i++)
    #define MS0(a) memset(a,0,sizeof(a))
    
    using namespace std;
    
    typedef long long ll;
    const int maxn=1000100;
    const int INF=1e9+10;
    
    int n,m;
    int a[maxn];
    char op[5];int L,R,k,p,c;
    
    ///---treap
    struct Node
    {
        int ch[2];
        int r,v;
        int sz;
    };Node tr[maxn];int rt[maxn];
    int tot1;
    int s[maxn],tot2;
    
    int newnode()
    {
        int o;
        if(tot2) o=s[tot2--];
        else o=++tot1;
        tr[o].ch[0]=tr[o].ch[1]=-1;
        tr[o].r=rand();tr[o].v=0;
        tr[o].sz=1;
        return o;
    }
    
    void up(int o)
    {
        tr[o].sz=1;
        if(~tr[o].ch[0]) tr[o].sz+=tr[tr[o].ch[0]].sz;
        if(~tr[o].ch[1]) tr[o].sz+=tr[tr[o].ch[1]].sz;
    }
    
    void rot(int &o,int d)
    {
        int k=tr[o].ch[d^1];
        tr[o].ch[d^1]=tr[k].ch[d];
        tr[k].ch[d]=o;
        up(o);up(k);
        o=k;
    }
    
    void Insert(int &o,int x)
    {
        if(o==-1){
            o=newnode();
            tr[o].v=x;
            return;
        }
        int d=x<tr[o].v?0:1;
        Insert(tr[o].ch[d],x);
        if(tr[tr[o].ch[d]].r>tr[o].r) rot(o,d^1);
        up(o);
    }
    
    void Remove(int &o,int x)
    {
        if(o==-1) return;
        if(tr[o].v==x){
            if(tr[o].ch[0]==-1) s[++tot2]=o,o=tr[o].ch[1];
            else if(tr[o].ch[1]==-1) s[++tot2]=o,o=tr[o].ch[0];
            else{
                int d=tr[tr[o].ch[0]].r>tr[tr[o].ch[1]].r?0:1;
                rot(o,d^1);
                Remove(tr[o].ch[d^1],x);
            }
            if(~o) up(o);
            return;
        }
        if(x<tr[o].v) Remove(tr[o].ch[0],x);
        else Remove(tr[o].ch[1],x);
        if(~o) up(o);
    }
    
    int getcnt(int &o,int y)
    {
        if(o==-1) return 0;
        if(y<=tr[o].v) return getcnt(tr[o].ch[0],y);
        int ls=tr[o].ch[0]==-1?0:tr[tr[o].ch[0]].sz;
        return ls+1+getcnt(tr[o].ch[1],y);
    }
    
    int getcnt2(int &o,int y)
    {
        if(o==-1) return 0;
        if(y<tr[o].v) return getcnt(tr[o].ch[0],y);
        int ls=tr[o].ch[0]==-1?0:tr[tr[o].ch[0]].sz;
        return ls+1+getcnt2(tr[o].ch[1],y);
    }
    
    ///---BIT
    int lowbit(int x)
    {
        return x&-x;
    }
    
    void add(int p,int c)
    {
        while(p<=n){
            Insert(rt[p],c);
            p+=lowbit(p);
        }
    }
    
    void del(int p,int c)
    {
        while(p<=n){
            Remove(rt[p],c);
            p+=lowbit(p);
        }
    }
    
    int sum(int p,int y)
    {
        int res=0;
        while(p){
            res+=getcnt(rt[p],y);
            p-=lowbit(p);
        }
        return res;
    }
    
    int sum2(int p,int y)
    {
        int res=0;
        while(p){
            res+=getcnt2(rt[p],y);
            p-=lowbit(p);
        }
        return res;
    }
    
    int bin(int L,int R,int l,int r,int k)
    {
        while(l<=r){
            int m=(l+r)>>1;
            int cnt=sum(R,m)-sum(L-1,m);
            int cnt2=sum2(R,m)-sum2(L-1,m);
            if(cnt<=k-1&&cnt2>=k) return m;
            if(k>cnt2) l=m+1;
            else r=m-1;
        }
    }
    
    void Init()
    {
        memset(rt,-1,sizeof(rt));
        tot1=tot2=0;
    }
    
    int main()
    {
        //freopen("in.txt","r",stdin);
        int T;cin>>T;
        while(T--){
            scanf("%d%d",&n,&m);
            Init();
            REP(i,1,n) scanf("%d",&a[i]);
            REP(i,1,n) add(i,a[i]);
            while(m--){
                scanf("%s",op);
                if(op[0]=='C'){
                    scanf("%d%d",&p,&c);
                    del(p,a[p]);
                    add(p,c);
                    a[p]=c;
                }
                else{
                    scanf("%d%d%d",&L,&R,&k);
                    printf("%d
    ",bin(L,R,0,INF,k));
                }
            }
        }
        return 0;
    }
    View Code

    注意下二分要算两个,小于和小于等于的。。。

    然后直接树状数组或线段树套上平衡树就可以了。

    没有AC不了的题,只有不努力的ACMER!
  • 相关阅读:
    iOSS--生成有logo的二维码
    inux网卡与MAC地址绑定方法总结
    Linux--多网卡的7种Bond模式
    Arp攻击实战
    5款免费Windows远程连接Linux桌面软件(VNC客户端)
    DenyHosts安装及配置
    Cacti完全使用手册 ( 让你快速个性化使用Cacti )
    解除被DenyHosts锁定的IP地址
    linux防止sshd被爆破(安装denyhosts)
    实现水电气一卡通 IC卡扇区分配
  • 原文地址:https://www.cnblogs.com/--560/p/5250031.html
Copyright © 2011-2022 走看看