• [模板]Splay


    题目描述

    您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:

    1. 插入 x 数
    2. 删除 x 数(若有多个相同的数,因只删除一个)
    3. 查询 x 数的排名(排名定义为比当前数小的数的个数 +1 。若有多个相同的数,因输出最小的排名)
    4. 查询排名为 x 的数
    5. 求 x 的前驱(前驱定义为小于 x ,且最大的数)
    6. 求 x 的后继(后继定义为大于 x ,且最小的数)

    输入输出格式

    输入格式

      第一行为 n ,表示操作的个数,下面 n 行每行有两个数 opt 和 xx ,opt 表示操作的序号

    输出格式

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

      1 #include<cstdio>
      2 #define root e[0].ch[1]
      3 using namespace std;
      4 const int maxn=1e5+5;
      5 int siz;
      6 struct cp{
      7     int fa,ch[2],num,v,siz;
      8 }e[maxn];
      9 inline void clear(int x){e[x]=(cp){0,0,0,0,0,0};}
     10 inline bool get(int x){return e[e[x].fa].ch[1]==x;}
     11 inline void con(int x,int fa,int f){e[e[x].fa=fa].ch[f]=x;}
     12 inline void update(int x){
     13     if(!x) return ;
     14     e[x].siz=e[x].num;
     15     if(e[x].ch[0]) e[x].siz+=e[e[x].ch[0]].siz;
     16     if(e[x].ch[1]) e[x].siz+=e[e[x].ch[1]].siz;
     17 }
     18 inline void rotate(int x){
     19     if(!e[x].fa) return ;
     20     int fa=e[x].fa,ffa=e[e[x].fa].fa;
     21     bool f1=get(x),f2=get(fa);
     22     con(e[x].ch[!f1],fa,f1),con(fa,x,!f1),con(x,ffa,f2);
     23     update(fa),update(x);
     24 }
     25 inline void splay(int x){
     26     for(int fa;fa=e[x].fa;rotate(x))
     27         if(e[fa].fa) rotate(get(x)==get(fa)?fa:x);
     28 }
     29 inline int findx(int v){
     30     int now=root;
     31     while(e[now].v!=v) now=e[now].ch[e[now].v<v];
     32     return now;
     33 }
     34 inline int find(int v){
     35     int now=root,s=1;
     36     while(e[now].v!=v){
     37         if(e[now].v<v) s+=e[e[now].ch[0]].siz+e[now].num;
     38         now=e[now].ch[e[now].v<v];
     39     }
     40     return s+e[e[now].ch[0]].siz;
     41 }
     42 inline int rank(int x){
     43     int now=root;
     44     while(1)
     45         if(e[e[now].ch[0]].siz>=x) now=e[now].ch[0];
     46         else{
     47             x-=e[e[now].ch[0]].siz;
     48             if(x<=e[now].num) return e[now].v;
     49             x-=e[now].num,now=e[now].ch[1];
     50         }
     51 }
     52 inline int pre(bool f){
     53     int now=e[root].ch[f];
     54     while(e[now].ch[!f]) now=e[now].ch[!f];
     55     return now;
     56 }
     57 inline void insert(int v){
     58     if(!root){
     59         e[++siz].v=v,con(siz,0,1),e[siz].siz=e[siz].num=1;
     60         return ;
     61     }
     62     int now=root,fa=0;
     63     while(1){
     64         if(e[now].v==v){
     65             ++e[now].num,++e[now].siz;
     66             if(fa) ++e[fa].siz;
     67             splay(now);
     68             return ;
     69         }
     70         now=e[fa=now].ch[e[now].v<v];
     71         if(!now){
     72             e[++siz].v=v,e[siz].num=e[siz].siz=1;
     73             con(siz,fa,e[fa].v<v),e[fa].siz++,splay(siz);
     74             return ;
     75         }
     76     }
     77 }
     78 inline void del(int v){
     79     int x=findx(v);
     80     splay(x);
     81     if(e[x].num>1) e[x].num--,e[x].siz--;
     82     else if(!e[x].ch[1]&&!e[x].ch[0]) clear(x),root=0;
     83     else if(!e[x].ch[1]||!e[x].ch[0])
     84         con(e[x].ch[!e[x].ch[0]],0,1),clear(x);
     85     else splay(pre(0)),con(e[x].ch[1],root,1),clear(x),e[root].siz--;
     86 }
     87 inline int read(){
     88     char ch=getchar();
     89     int x=0,f=1;
     90     while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
     91     while(ch>='0'&&ch<='9') x=x*10+(ch^48),ch=getchar();
     92     return x*f;
     93 }
     94 int main(){
     95     int n=read(),f,x;
     96     while(n--){
     97         f=read(),x=read();
     98         if(f==1) insert(x);
     99         else if(f==2) del(x);
    100         else if(f==3) printf("%d
    ",find(x));
    101         else if(f==4) printf("%d
    ",rank(x));
    102         else{
    103             insert(x);
    104             printf("%d
    ",e[pre(f-5)].v);
    105             del(x);
    106         }
    107     }
    108     return 0;
    109 }
    Splay
  • 相关阅读:
    Oracle 游标使用全解(转)
    Oracle临时表GLOBAL TEMPORARY TABLE
    jQuery 增加 删除 修改select option
    万恶的 “缺少标识符、字符串或数字”
    关于window的resize事件
    flex关于字符串转Boolean .
    UpdatePanel完成后调用js
    JS 弹出模态窗口解决方案
    Python:扫描目录下的所有文件
    Nginx笔记总结二十一:隐藏或者混淆nginx返回的Server信息
  • 原文地址:https://www.cnblogs.com/RisingGods/p/9126407.html
Copyright © 2020-2023  润新知