• bzoj3224 普通平衡树(splay 模板)


    3224: Tyvj 1728 普通平衡树

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 11427  Solved: 4878
    [Submit][Status][Discuss]

    Description

    您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
    1. 插入x数
    2. 删除x数(若有多个相同的数,因只删除一个)
    3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
    4. 查询排名为x的数
    5. 求x的前驱(前驱定义为小于x,且最大的数)
    6. 求x的后继(后继定义为大于x,且最小的数)

    Input

    第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号(1<=opt<=6)

    Output

    对于操作3,4,5,6每行输出一个数,表示对应答案

    Sample Input

    10
    1 106465
    4 1
    1 317721
    1 460929
    1 644985
    1 84185
    1 89851
    6 81968
    1 492737
    5 493598

    Sample Output

    106465
    84185
    492737

    HINT

    1.n的数据范围:n<=100000

    2.每个数的数据范围:[-1e7,1e7]

    数据如下http://pan.baidu.com/s/1jHMJwO2

    Source

     
    #include <cstdio>
    #define Maxn 1000000
    using namespace std;
    int f[Maxn];//father
    int ch[Maxn][2];//child ; 0 for left ; 1 for right
    int key[Maxn];//key
    int cnt[Maxn];//value
    int siz[Maxn];//size of subtree
    int sz,root;//size of tree and root
    //clear the ndoe
    
    void clear(int x)
    {
        ch[x][0]=ch[x][1]=f[x]=cnt[x]=key[x]=siz[x]=0;
    }
    
    //rightson return 1;left son return 0
    int getson(int x)
    {
        return ch[f[x]][1]==x;
    }
    
    //update the size
    void update(int x)
    {
        siz[x]=cnt[x];
        if (ch[x][0]) siz[x]+=siz[ch[x][0]];
        if (ch[x][1]) siz[x]+=siz[ch[x][1]];
    }
    
    //retation
    int rotate(int x)
    {
        int fa=f[x],fafa=f[fa],k=getson(x);
        ch[fa][k]=ch[x][k^1];f[ch[fa][k]]=fa;
        ch[x][k^1]=fa;f[fa]=x;
        f[x]=fafa;
        if (fafa)
            ch[fafa][ch[fafa][1]==fa]=x;
        update(fa);update(x);
    }
    
    //rotate until x is the root
    void splay(int x)
    {
        for (int fa;fa=f[x];rotate(x))
            if (f[fa])
                rotate(getson(x)==getson(fa) ? fa : x);
        root=x;
    }
    
    int pre()
    {
        int now=ch[root][0];
        while(ch[now][1])
            now=ch[now][1];
        return now;
    }
    
    int nex()
    {
        int now=ch[root][1];
        while(ch[now][0])
            now=ch[now][0];
        return now;
    }
    
    //find x's pos
    int findpos(int v)
    {
        int now=root,ans=0;
        while(1)
        {
            if (v<key[now])
                now=ch[now][0];
            else
            {
                ans+=ch[now][0]?siz[ch[now][0]]:0;
                if (v==key[now]) 
                {
                    splay(now);
                    return ans+1;
                }
                ans+=cnt[now];
                now=ch[now][1];
            }
        }
    }
    
    //find pos's x
    int findx(int x)
    {
        int now=root;
        while(1)
        {
            if (ch[now][0] && x<=siz[ch[now][0]])
                now=ch[now][0];
            else
            {
                int temp=(ch[now][0]?siz[ch[now][0]]:0)+cnt[now];
                if (x<=temp)
                    return key[now];
                x-=temp;
                now=ch[now][1];
            }
        }
    }
    
    //ceate a new splay node
    void create(int v)
    {
        sz++;
        ch[sz][0]=ch[sz][1]=f[sz]=0;
        key[sz]=v;
        cnt[sz]=1;
        siz[sz]=1;
        //root=sz;
    }
    
    //insert a node
    void insert(int v)
    {
        if (!root)
            create(v),root=sz;
        else
        {
            int now=root,fa=0;
            while(1)
            {
                if (key[now]==v)
                {
                    cnt[now]++;
                    update(now);update(fa);
                    splay(now);
                    break;
                }
                fa=now;
                now=ch[fa][v>key[fa]];
                if (!now)
                {
                    create(v);
                    f[sz]=fa;
                    ch[fa][v>key[fa]]=sz;
                    update(fa);
                    splay(sz);
                    break;
                }
            }
        }
    }
    
    void del(int x)
    {
        int t=findpos(x);
        if (cnt[root]>1) 
        {
            cnt[root]--;
            update(root);
            return;
        }
        //none
        if (!ch[root][0] && !ch[root][1])
        {
            clear(root);
            root=0;
            return;
        }
        //one
        if (!ch[root][1])
        {
            int temp=root;
            root=ch[root][0];
            f[root]=0;
            clear(temp);
            return;
        }
        else
        if (!ch[root][0])
        {
            int temp=root;
            root=ch[root][1];
            f[root]=0;
            clear(temp);
            return;
        }
        //two
        int pre1=pre(),temp=root;
        splay(pre1);
        f[ch[temp][1]]=root;
        ch[root][1]=ch[temp][1];
        clear(temp);
        update(root);
    }
    
    int main()
    {  
        int n,opt,x;  
        scanf("%d",&n);  
        for (int i=1;i<=n;++i)
        {  
            scanf("%d%d",&opt,&x);  
            switch(opt)
            {  
                case 1: insert(x); break;  
                case 2: del(x); break;  
                case 3: printf("%d
    ",findpos(x)); break;  
                case 4: printf("%d
    ",findx(x)); break;  
                case 5: insert(x); printf("%d
    ",key[pre()]); del(x); break;
                case 6: insert(x); printf("%d
    ",key[nex()]); del(x); break;
            }  
        }  
    }
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    
    #define N 1000000
    
    using namespace std;
    int f[N],ch[N][2],key[N],cnt[N],siz[N],sz,root;
    
    inline int read()
    {
        int x=0,f=1;char c=getchar();
        while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    
    inline void update(int x)
    {
        siz[x]=cnt[x];
        if(ch[x][0]) siz[x]+=siz[ch[x][0]];
        if(ch[x][1]) siz[x]+=siz[ch[x][1]];
    }
    
    int pre()
    {
        int now=ch[root][0];
        while(ch[now][1]) now=ch[now][1];return now;
    }
    
    int nex()
    {
        int now=ch[root][1];
        while(ch[now][0]) now=ch[now][0];return now;
    }
    
    inline int getson(int x)
    {
        return ch[f[x]][1]==x;
    }
    
    inline void rorate(int x)
    {
        int fa=f[x],ffa=f[fa],k=getson(x);
        ch[fa][k]=ch[x][k^1];f[ch[fa][k]]=fa;
        ch[x][k^1]=fa;f[fa]=x;f[x]=ffa;
        if(ffa)ch[ffa][ch[ffa][1]==fa]=x;
        update(fa);update(x);
    }
    
    void splay(int x)
    {
        for(int fa;fa=f[x];rorate(x))
          if(f[fa]) rorate(getson(x)==getson(fa)?fa:x);
        root=x;
    }
    
    int findpos(int x)
    {
        int now=root,ans=0;
        while(1)
        {
            if(x<key[now]) now=ch[now][0];
            else 
            {
                ans+=ch[now][0]?siz[ch[now][0]]:0;
                if(x==key[now])
                {
                    splay(now);return ans+1;
                }
                ans+=cnt[now];now=ch[now][1];
            }
        }
    }
    
    int findx(int x)
    {
        int now=root;
        while(1)
        {
            if(ch[now][0]&&x<=siz[ch[now][0]]) now=ch[now][0];
            else
            {
                int tmp=(ch[now][0]?siz[ch[now][0]]:0)+cnt[now];
                if(x<=tmp) return key[now];
                x-=tmp;now=ch[now][1];
            }
        }
    }
    
    void clear(int x)
    {
        ch[x][0]=ch[x][1]=cnt[x]=siz[x]=key[x]=f[x]=0;
    }
    
    void creat(int x)
    {
        sz=sz+1;key[sz]=x;cnt[sz]=siz[sz]=1;
        ch[sz][0]=ch[sz][1]=f[sz]=0;
    }
    
    void insert(int x)
    {
        if(!root) creat(x),root=sz;
        else
        {
            int now=root,fa=0;
            while(1)
            {
                if(key[now]==x)
                {
                    cnt[now]++;siz[now]++;splay(now);
                    break;
                }
                fa=now;now=ch[fa][x>key[fa]];
                if(!now)
                {
                    creat(x);f[sz]=fa;ch[fa][x>key[fa]]=sz;
                    splay(sz);break;
                }
            }
        }
    }
    
    void del(int x)
    {
        int t=findpos(x);
        if(cnt[root]>1)
        {
            cnt[root]--;siz[root]--;return;
        }
        if(!ch[root][0]&&!ch[root][1])
        {
            clear(root);root=0;return;
        }
        if(!ch[root][0])
        {
            int tmp=root;root=ch[root][1];f[root]=0;
            clear(tmp);return;
        }
        if(!ch[root][1])
        {
            int tmp=root;root=ch[root][0];f[root]=0;
            clear(tmp);return;
        }
        int pre1=pre(),tmp=root;splay(pre1);
        ch[root][1]=ch[tmp][1];f[ch[tmp][1]]=root;
        clear(tmp);update(root);
    }
    
    int main()
    {
        int n,opt,x;
        n=read();
        for(int i=1;i<=n;i++)
        {
            opt=read();x=read();
            switch(opt)
            {
                case 1 :insert(x);break;
                case 2 :del(x);break; 
                case 3 :printf("%d
    ",findpos(x));break;
                case 4 :printf("%d
    ",findx(x));break;
                case 5 :insert(x);printf("%d
    ",key[pre()]);del(x);break;
                case 6 :insert(x);printf("%d
    ",key[nex()]);del(x);break; 
            }
        }
    }
    我的马蜂
    折花枝,恨花枝,准拟花开人共卮,开时人去时。 怕相思,已相思,轮到相思没处辞,眉间露一丝。
  • 相关阅读:
    实时监听输入框值变化的完美方案:oninput & onpropertychange
    展示两行,超出用。。。表示
    修改下拉框滚动条样式
    js单线程工作
    锚点
    火狐图片乱码
    解决重复提交的几种方法
    forward和redirect的区别
    form表单刷新自动提交
    addEventListener和attachEvent的区别
  • 原文地址:https://www.cnblogs.com/L-Memory/p/6556921.html
Copyright © 2020-2023  润新知