zoukankan      html  css  js  c++  java
  • 【模板】Splay

      1 #include<cstdio>
      2 #include<algorithm>
      3 #define ls (a[u].l)
      4 #define rs (a[u].r)
      5 #define fa (a[u].f)
      6 using namespace std;
      7 const int maxn=200010;
      8 int n,opt,x,root,size;
      9 struct tree{int f,l,r,val,cnt,size;}a[maxn];
     10 inline int read(){
     11     int k=0,f=1; char c=getchar();
     12     while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
     13     while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar();
     14     return k*f;
     15 }
     16 inline void clear(int u){a[u]=(tree){0,0,0,0,0,0};}//将当前结点的各项值都清零 
     17 inline bool which(int u){return a[fa].l==u;}//判断当前节点是父亲的左孩子还是右孩子
     18 inline void update(int u){//发生修改之后,更新当前节点的size值 
     19     if(!u) return;
     20     a[u].size=a[u].cnt;
     21     if(ls) a[u].size+=a[ls].size;
     22     if(rs) a[u].size+=a[rs].size;
     23 }
     24 inline void rotate(int u){
     25     int f=a[u].f,gf=a[f].f;
     26     if(which(u)){
     27         a[f].l=a[u].r;
     28         a[rs].f=f;
     29         a[u].r=f;
     30     }
     31     else{
     32         a[f].r=a[u].l;
     33         a[ls].f=f;
     34         a[u].l=f;
     35     }
     36     a[f].f=u; a[u].f=gf;
     37     if(gf){
     38         if(a[gf].l==f) a[gf].l=u;
     39         else a[gf].r=u;
     40     }
     41     update(f); update(u);
     42 } 
     43 inline void splay(int u){
     44     for(int f;f=a[u].f;rotate(u)){
     45         //printf("QAQ %d
    ",f);
     46         if(a[f].f) rotate(which(u)==which(f)?f:u);
     47     }
     48     root=u;
     49 }
     50 inline int pre(){
     51      int now=a[root].l;
     52      while(a[now].r) now=a[now].r;
     53      return now;
     54 }
     55 inline int next(){
     56      int now=a[root].r;
     57      while(a[now].l) now=a[now].l;
     58      return now;
     59 }
     60 inline void insert(int val){
     61     if(!root){a[root=(++size)]=(tree){0,0,0,val,1,1}; return;}
     62     int now=root,f=0;
     63     while(1){
     64         if(a[now].val==val){
     65             a[now].cnt++;
     66             update(now); update(f); splay(now);
     67             break;
     68         }
     69         f=now; now=(val>a[now].val)?a[now].r:a[now].l;
     70         if(!now){
     71             a[++size]=(tree){f,0,0,val,1,1};
     72             if(val>a[f].val) a[f].r=size; else a[f].l=size;
     73             update(f); splay(size);
     74             break;
     75         }
     76     }
     77 }
     78 inline int qrank(int val){
     79      int ans=0,now=root;
     80      while(1){
     81          if(val<a[now].val) now=a[now].l;
     82          else{
     83              if(a[now].l) ans+=a[a[now].l].size;
     84              if(val==a[now].val){splay(now); return ans+1;}
     85              ans+=a[now].cnt;
     86              now=a[now].r;
     87          }
     88      }
     89 }
     90 inline int qval(int rank){
     91     int now=root;
     92      while(1){
     93          if(a[now].l&&rank<=a[a[now].l].size) now=a[now].l;
     94          else{
     95              int tmp=(a[now].l?a[a[now].l].size:0)+a[now].cnt;
     96              if(rank<=tmp) return a[now].val;
     97              rank-=tmp; now=a[now].r;
     98          }
     99      }
    100 }
    101 inline void del(int u){
    102     int whatever=qrank(u);
    103     if(a[root].cnt>1){a[root].cnt--; update(root); return;}//不止有一个要删除的值,直接cnt-1 
    104     if(!a[root].l&&!a[root].r){clear(root); root=0; return;}//只有一个点
    105     if(!a[root].l){//只有左孩子
    106         int oldrt=root;
    107         a[root=a[root].r].f=0;
    108         clear(oldrt);
    109         return;
    110     }
    111     if(!a[root].r){//只有右孩子
    112         int oldrt=root;
    113         a[root=a[root].l].f=0;
    114         clear(oldrt);
    115         return;
    116     }
    117     int prefix=pre(),oldrt=root;//有两个孩子
    118     splay(prefix);//新根为u的前驱
    119     a[root].r=a[oldrt].r;
    120     a[a[oldrt].r].f=root;
    121     clear(oldrt); update(root);
    122 }
    123 void out(int u){
    124     if(ls) out(ls);
    125     for(int i=1;i<=a[u].cnt;i++)printf("%d ",a[u].val);
    126     if(rs) out(rs);
    127 }
    128 int main(){
    129     n=read();
    130      while(n--){
    131          opt=read(); x=read();
    132          if(opt==1) insert(x);//插入x 
    133          if(opt==2) del(x);//删除x 
    134          if(opt==3) printf("%d
    ",qrank(x));//求x的排名 
    135          if(opt==4) printf("%d
    ",qval(x));//求排名为x的数 
    136          if(opt==5) insert(x),printf("%d
    ",a[pre()].val),del(x);//求x的前驱 
    137         if(opt==6) insert(x),printf("%d
    ",a[next()].val),del(x);//求x的后继
    138         //printf("[ "); out(root); puts("]");
    139      }
    140 }
    View Code

    洛谷 3369

  • 相关阅读:
    常用正则表达式大全摘录
    非常好用的CSS样式重置表
    Vue2.0 Props双向绑定报错简易处理办法
    kuangbin带我飞QAQ DLX之一脸懵逼
    乘法逆元+快速幂
    kuangbin带我飞QAQ 线段树
    kuangbin带我飞QAQ 最短路
    uva11401:Triangle Counting 递推 数学
    分块
    今日头条”杯2018年湖北省赛(网络赛)
  • 原文地址:https://www.cnblogs.com/DriverLao/p/8253734.html
Copyright © 2011-2022 走看看