zoukankan      html  css  js  c++  java
  • 【BZOJ3224】Tyvj 1728 普通平衡树 Splay

    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]

    Source

    平衡树

     Splay模板题,膜了YveH爷的模板,不过代码好长,常数还很大。。。好歹是打粗来了

      1 #include <cstdio>
      2 using namespace std;
      3 struct SplayNode
      4 {
      5     SplayNode *fa,*ch[2];
      6     SplayNode();
      7     int data,num,size;
      8     int chr() {return this==fa->ch[1];}
      9     void updata() { size=ch[0]->size+ch[1]->size+num;}
     10 }*null;
     11 SplayNode::SplayNode() {fa=ch[0]=ch[1]=null; size=0; num=1;}
     12 int n;
     13 namespace Splay
     14 {
     15     SplayNode *Root;
     16     void MakeTree()
     17     {
     18         null=new SplayNode;
     19         *null=SplayNode();
     20         Root=null;
     21     }
     22     void rotate(SplayNode *x)
     23     {
     24         SplayNode *r=x->fa;
     25         if (r==null || x==null) return;
     26         int t=x->chr();
     27         r->ch[t]=x->ch[t^1];
     28         r->ch[t]->fa=r;
     29         if (r->fa==null) Root=x;
     30         else r->fa->ch[r->chr()]=x;
     31         x->fa=r->fa;
     32         x->ch[t^1]=r;
     33         r->fa=x;
     34         r->updata();
     35         x->updata();
     36     }
     37     void splay(SplayNode *x,SplayNode *y)
     38     {
     39         for (;x->fa!=y;rotate(x))
     40             if (x->fa->fa!=y)
     41                 if (x->chr()==x->fa->chr()) rotate(x->fa);
     42                 else rotate(x);
     43     } 
     44     void insert(int v)
     45     {
     46         SplayNode *r=Root;
     47         if (Root==null)
     48         {
     49             Root=new SplayNode;
     50             Root->data=v;
     51             Root->updata();
     52             return;
     53         }
     54         if (Root->data==v)
     55         {
     56             Root->num++;
     57             Root->updata();
     58             return;
     59         }
     60         while (r->ch[r->data<v]!=null)
     61         {
     62             r=r->ch[r->data<v];
     63             if (r->data==v)
     64             {
     65                 r->num++;
     66                 splay(r,null);
     67                 return;
     68             }
     69         }
     70         r->ch[r->data<v]=new SplayNode;
     71         r->ch[r->data<v]->data=v;
     72         r->ch[r->data<v]->fa=r;
     73         splay(r->ch[r->data<v],null);
     74     }
     75     SplayNode *Kth(int k)
     76     {
     77         SplayNode *r=Root;
     78         while (r!=null)
     79         {
     80             if (k<=r->ch[0]->size) r=r->ch[0];
     81             else if (k>=r->ch[0]->size+1 && k<=r->ch[0]->size+r->num) return r;
     82             else 
     83             {
     84                 k=k-r->ch[0]->size-r->num;
     85                 r=r->ch[1];
     86             }
     87         }
     88         return r;
     89     }
     90     SplayNode *find(int v)
     91     {
     92         SplayNode *r=Root;
     93         while (r!=null)
     94         {
     95             if (r->data==v) 
     96             {
     97                 splay(r,null);
     98                 return r;
     99             }
    100             r=r->ch[r->data<v];
    101         }
    102         return null;
    103     }
    104     SplayNode *pre()
    105     {
    106         SplayNode *r=Root->ch[0];
    107         if (r==null) return null;
    108         while (r->ch[1]!=null) r=r->ch[1];
    109         return r;
    110     }
    111     SplayNode *suc()
    112     {
    113         SplayNode *r=Root->ch[1];
    114         if (r==null) return null;
    115         while (r->ch[0]!=null) r=r->ch[0];
    116         return r;
    117     }
    118     void del(int v)
    119     {
    120         find(v);
    121         SplayNode *q=pre();
    122         SplayNode *p=suc();
    123         if (q==null && p==null)
    124             if (Root->num==1) Root=null;
    125             else Root->num--,Root->updata();
    126         if (q==null)
    127         {
    128             splay(p,null);
    129             if (Root->ch[0]->num==1) Root->ch[0]=null,Root->updata();
    130             else Root->ch[0]->num--,splay(Root->ch[0],null);
    131             return;
    132         }
    133         if (p==null)
    134         {
    135             splay(q,null);
    136             if (Root->ch[1]->num==1) Root->ch[1]=null,Root->updata();    
    137             else Root->ch[1]->num--,splay(Root->ch[1],null);
    138             return;
    139         }
    140         splay(q,null);
    141         splay(p,q);
    142         if (p->ch[0]->num==1) p->ch[0]=null,p->updata();
    143         else p->ch[0]->num--,splay(p->ch[0],null);
    144         return;
    145     }
    146 }
    147 void solve()
    148 {
    149     int temp,x;
    150     scanf("%d",&n);
    151     for (int i=1;i<=n;i++)
    152     {
    153         scanf("%d%d",&temp,&x);
    154         if (temp==1) Splay::insert(x);
    155         if (temp==2) Splay::del(x);
    156         if (temp==3) printf("%d
    ",Splay::find(x)->ch[0]->size+1);
    157         if (temp==4) printf("%d
    ",Splay::Kth(x)->data);
    158         if (temp==5) 
    159         {
    160             Splay::insert(x);
    161             printf("%d
    ",Splay::pre()->data);
    162             Splay::del(x);
    163         }
    164         if (temp==6)
    165         { 
    166             Splay::insert(x);
    167             printf("%d
    ",Splay::suc()->data);
    168             Splay::del(x);
    169         }
    170     }
    171 }
    172 int main()
    173 {
    174     Splay::MakeTree();
    175     solve(); 
    176     return 0;
    177 }
    View Code
    —Anime Otaku Save The World.
  • 相关阅读:
    [NOI2004]cashier 郁闷的出纳员
    [HNOI2004]宠物收养所
    [HNOI2002]营业额统计
    浅谈算法——莫比乌斯反演
    浅谈算法——splay
    [POI2006]Tet-Tetris 3D
    BZOJ2733 [HNOI2012]永无乡 【线段树合并】
    UOJ279 【UTR #2】题目交流通道
    UOJ278 【UTR #2】题目排列顺序
    POJ2761 Feed the dogs
  • 原文地址:https://www.cnblogs.com/DMoon/p/5281382.html
Copyright © 2011-2022 走看看