• [Tyvj 1728] 普通平衡树


    大名鼎鼎的板子题w

    照例先贴题面

    Describtion

    您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
    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]
    此时无声胜有声【大雾
    这种时候应该选择直接贴袋马w
    后续可能会更新不同做法QwQ
    目前为止只用带旋Treap A掉这题感觉我好菜啊w
    教练我想学Splay我想学无旋Treap我想学SBT我想学替罪羊QwQ
    还要AVL RBT vEBT (教练:我就不信你能学得了这么多还不滚回去打字符串去)
    UPD:Splay Tree成功AC
    GitHub:
    Backup:
      1 #include <ctime>
      2 #include <queue>
      3 #include <cstdio>
      4 #include <cstring>
      5 #include <cstdlib>
      6 #include <iostream>
      7 #include <algorithm>
      8 using namespace std;
      9 
     10 const int INF=0x7FFFFFFF;
     11 #define lch chd[0]
     12 #define rch chd[1]
     13 #define kch chd[k]
     14 #define xch chd[k^1]
     15 
     16 class Treap{
     17 private:
     18     int v;
     19     int k;
     20     int s;
     21 public:
     22     Treap* chd[2];
     23     Treap(int v=0,Treap* l=NULL,Treap* r=NULL,int s=1,int k=rand()){
     24         this->v=v;
     25         this->s=s;
     26         this->k=k;
     27         this->chd[0]=l;
     28         this->chd[1]=r;
     29     }
     30     inline void Maintain(){
     31         if(this->exist())
     32             this->s=this->lch->size()+this->rch->size()+1;
     33     }
     34     inline int value(){
     35         return this==NULL?0:v;
     36     }
     37     inline int key(){
     38         return this==NULL?INF:k;
     39     }
     40     inline int size(){
     41         return this==NULL?0:s;
     42     }
     43     inline bool empty(){
     44         return this==NULL;
     45     }
     46     inline bool exist(){
     47         return this!=NULL;
     48     }
     49 }*Root=NULL;
     50 
     51 void Insert(Treap*&,int);
     52 void Delete(Treap*&,int);
     53 void Rotate(Treap*&,int);
     54 int Rank(int);
     55 int Kth(int);
     56 int Predecessor(int);
     57 int Successor(int);
     58 
     59 inline void PrintTree(){
     60     queue<Treap*> q;
     61     q.push(Root);
     62     while(!q.empty()){
     63         if(q.front()->empty()){
     64             puts("(v=@@@,s=@@@,k=@@@)");
     65         }
     66         else{
     67             printf("(v=%d,s=%d,k=%d)
    ",q.front()->value(),q.front()->size(),q.front()->key());
     68             q.push(q.front()->lch);
     69             q.push(q.front()->rch);
     70         }
     71         q.pop();
     72     }
     73     printf("
    
    
    
    ");
     74 }
     75 
     76 int main(){
     77     freopen("phs.in","r",stdin);
     78     freopen("phs.out","w",stdout);
     79     srand(time(NULL));
     80     int n,type,num;
     81     scanf("%d",&n);
     82     for(int i=0;i<n;i++){
     83         scanf("%d%d",&type,&num);
     84         if(type==1)
     85             Insert(Root,num);
     86         else if(type==2)
     87             Delete(Root,num);
     88         else if(type==3)
     89             printf("%d
    ",Rank(num));
     90         else if(type==4)
     91             printf("%d
    ",Kth(num));
     92         else if(type==5)
     93             printf("%d
    ",Predecessor(num));
     94         else if(type==6)
     95             printf("%d
    ",Successor(num));
     96         // PrintTree();
     97     }
     98     return 0;
     99 }
    100 
    101 void Insert(Treap* &root,int x){
    102     if(root->empty()){
    103         root=new Treap(x);
    104         return;
    105     }
    106     else{
    107         int k=x<root->value();
    108         Insert(root->xch,x);
    109         root->Maintain();
    110         if(root->xch->key()>root->key())
    111             Rotate(root,k);
    112     }
    113 }
    114 
    115 void Delete(Treap* &root,int x){
    116     if(root->empty())
    117         return;
    118     else{
    119         if(root->value()==x){
    120             if(root->lch->exist()&&root->rch->exist()){
    121                 int k=root->lch->key()>root->rch->key();
    122                 Rotate(root,k);
    123                 Delete(root->kch,x);
    124             }
    125             else{
    126                 Treap* tmp=root;
    127                 if(root->lch->exist())
    128                     root=root->lch;
    129                 else
    130                     root=root->rch;
    131                 delete tmp;
    132             }
    133         }
    134         else
    135             Delete(root->chd[x>=root->value()],x);
    136         root->Maintain();
    137     }
    138 }
    139 
    140 inline int Rank(int x){
    141     Treap* root=Root;
    142     int ans=1;
    143     while(root->exist()){
    144         if(x<=root->value())
    145             root=root->lch;
    146         else{
    147             ans+=root->lch->size()+1;
    148             root=root->rch;
    149         }
    150     }
    151     return ans;
    152 }
    153 
    154 inline int Kth(int x){
    155     Treap* root=Root;
    156     int k;
    157     while(root->exist()){
    158         k=root->lch->size()+1;
    159         if(x<k)
    160             root=root->lch;
    161         else if(x==k)
    162             return root->value();
    163         else{
    164             x-=k;
    165             root=root->rch;
    166         }
    167     }
    168     return 0;
    169 }
    170 
    171 inline int Predecessor(int x){
    172     return Kth(Rank(x)-1);
    173 }
    174 
    175 inline int Successor(int x){
    176     return Kth(Rank(x+1));
    177 }
    178 
    179 inline void Rotate(Treap* &root,int k){
    180     Treap* tmp=root->xch;
    181     root->xch=tmp->kch;
    182     root->Maintain();
    183     tmp->kch=root;
    184     tmp->Maintain();
    185     root=tmp;
    186 }
    Treap
      1 #include <cstdio>
      2 #include <cstring>
      3 #include <cstdlib>
      4 #include <iostream>
      5 #include <algorithm>
      6 
      7 #define lch chd[0]
      8 #define rch chd[1]
      9 #define kch chd[k]
     10 #define xch chd[k^1]
     11 
     12 const int INF=0x7FFFFFFF;
     13 
     14 class SplayTree{
     15 private:
     16     struct Node{
     17         int k;
     18         int s;
     19         Node* prt;
     20         Node* chd[2];
     21         Node(const int& key){
     22             this->k=key;
     23             this->s=1;
     24             this->prt=NULL;
     25             this->lch=NULL;
     26             this->rch=NULL;
     27         }
     28         inline int size(){
     29             return this==NULL?0:this->s;
     30         }
     31         inline int key(){
     32             return this==NULL?0:this->k;
     33         }
     34         inline void Maintain(){
     35             if(this!=NULL)
     36                 this->s=this->lch->size()+this->rch->size()+1;
     37         }
     38         inline int Pos(){
     39             return this==this->prt->lch;
     40         }
     41     }*root;
     42 
     43     void Rotate(Node* root,int k){
     44         Node* tmp=root->xch;
     45         if(root->prt==NULL)
     46             this->root=tmp;
     47         else if(root->prt->lch==root)
     48             root->prt->lch=tmp;
     49         else
     50             root->prt->rch=tmp;
     51         tmp->prt=root->prt;
     52         root->xch=tmp->kch;
     53         if(root->xch!=NULL)
     54             root->xch->prt=root;
     55         tmp->kch=root;
     56         root->prt=tmp;
     57         root->Maintain();
     58         tmp->Maintain();
     59     }
     60 
     61     void Splay(Node* root,Node* prt=NULL){
     62         while(root->prt!=prt){
     63             int k=root->Pos();
     64             if(root->prt->prt==prt){
     65                 this->Rotate(root->prt,k);
     66             }
     67             else{
     68                 int d=root->prt->Pos();
     69                 this->Rotate(k==d?root->prt->prt:root->prt,k);
     70                 this->Rotate(root->prt,d);
     71             }
     72         }
     73     }
     74 public:
     75     Node* Kth(int pos){
     76         Node* root=this->root;
     77         while(root!=NULL){
     78             int k=root->lch->size()+1;
     79             if(pos<k)
     80                 root=root->lch;
     81             else if(pos==k)
     82                 return root;
     83             else{
     84                 pos-=k;
     85                 root=root->rch;
     86             }
     87         }
     88         return NULL;
     89     }
     90 
     91     int Rank(const int& key){
     92         Node* root=this->root;
     93         int rank=1;
     94         while(root!=NULL){
     95             if(root->key()<key){
     96                 rank+=root->lch->size()+1;
     97                 root=root->rch;
     98             }
     99             else
    100                 root=root->lch;
    101         }
    102         return rank;
    103     }
    104 
    105     void Insert(const int& key){
    106         int pos=this->Rank(key)-1;
    107         this->Splay(this->Kth(pos));
    108         this->Splay(this->Kth(pos+1),this->root);
    109         Node* tmp=new Node(key);
    110         this->root->rch->lch=tmp;
    111         tmp->prt=this->root->rch;
    112         this->root->rch->Maintain();
    113         this->root->Maintain();
    114     }
    115 
    116     void Delete(const int& key){
    117         int pos=this->Rank(key);
    118         this->Splay(this->Kth(pos-1));
    119         this->Splay(this->Kth(pos+1),root);
    120         delete this->root->rch->lch;
    121         this->root->rch->lch=NULL;
    122         this->root->rch->Maintain();
    123         this->root->Maintain();
    124     }
    125 
    126     inline int Predecessor(const int& key){
    127         return this->Kth(this->Rank(key)-1)->key();
    128     }
    129 
    130     inline int Successor(const int& key){
    131         return this->Kth(this->Rank(key+1))->key();
    132     }
    133 
    134     SplayTree(){
    135         this->root=new Node(-INF);
    136         this->root->rch=new Node(INF);
    137         this->root->rch->prt=this->root;
    138         this->root->rch->Maintain();
    139         this->root->Maintain();
    140     }
    141 };
    142 
    143 int main(){
    144 #ifndef ASC_LOCAL
    145     freopen("phs.in","r",stdin);
    146     freopen("phs.out","w",stdout);
    147 #endif
    148     SplayTree* T=new SplayTree();
    149     int t,opt,key;
    150     scanf("%d",&t);
    151     while(t--){
    152         scanf("%d%d",&opt,&key);
    153         if(opt==1)
    154             T->Insert(key);
    155         else if(opt==2)
    156             T->Delete(key);
    157         else if(opt==3)
    158             printf("%d
    ",T->Rank(key)-1);
    159         else if(opt==4)
    160             printf("%d
    ",T->Kth(key+1)->key());
    161         else if(opt==5)
    162             printf("%d
    ",T->Predecessor(key));
    163         else
    164             printf("%d
    ",T->Successor(key));
    165     }
    166     return 0;
    167 }
    Splay
  • 相关阅读:
    java基础学习——编辑器的使用(一)
    nginx配置文件重写url不带index.php
    解决Too many open files问题
    内存溢出
    NetworkInterface获取主机ip,判断内外网
    克隆
    StringUtil
    Model与Record转换适配
    字符串操作工具类
    利用反射机制动态的调用类信息
  • 原文地址:https://www.cnblogs.com/rvalue/p/7191893.html
Copyright © 2020-2023  润新知