普通平衡树Tyvj1728、luogu P3369 (splay)

  存个模板,这次是splay的;

题目见这个题解:    <--(鼠标移到这儿)

代码如下:

  1 #include<cstdio>
  2 #define INF 2147483647
  3 using namespace std;
  4 struct poo
  5 {
  6     int size,cnt,value;
  7     int ch[2],fa;
  8 }data[100001];
  9 int root,tot,x,n;
 10 void insert();//插入v=x(x为全程量)的点// 
 11 void del();//删除v=x(x为全程量)的点//
 12 int rank();//查找v=x(x为全程量)的点的排名 //
 13 int find();//查找排名为x(x为全程量)的点 //
 14 int  las(int );//查找v=x(x为全程量)的点的前驱含splay// 
 15 int  nex(int );//查找v=x(x为全程量)的点的后继含splay//
 16 void splay(int );//含roll//
 17 void roll(int );//含up//
 18 int get_wh(int );//查找v=x(x为传参)的点的poo编号含splay//
 19 int get(int );//查找poo=x(x为传参)的点的fa的相应儿子//
 20 void cut(int );//切掉poo=x(x为传参)的点//
 21 void make_data(int );//建立fa=f(f为传参)的点//
 22 void up(int );//up poo=x(x为传参)的点//
 23 void print(int );
 24 void puttree(int ,int );
 25 int main()
 26 {
 27 //    freopen("input4.in","r",stdin);
 28 //    freopen("splay.out","w",stdout);
 29     int i,j;
 30     scanf("%d",&n);
 31     root=0;
 32     for(i=1;i<=n;i++){
 33         scanf("%d%d",&j,&x);
 34         switch(j){
 35             case 1:insert();break;
 36             case 2:   del();break;
 37             case 3:  printf("%d
",rank());break;
 38             case 4:  printf("%d
",find());break;
 39             case 5:  insert();printf("%d
", las(x));del();break;
 40             case 6:  insert();printf("%d
", nex(x));del();break;
 41         }
 42     }
 43 }
 44 void insert(){
 45     if(!root){
 46         root=++tot;
 47         make_data(0);
 48         return;
 49     }
 50     int i=root,j=0;
 51     while(i){
 52         if(data[i].value==x){
 53             data[i].cnt++;data[i].size++;
 54             splay(i);
 55             return;
 56         }
 57         if(data[i].value>x)
 58             j=i,i=data[i].ch[0];
 59         else
 60             j=i,i=data[i].ch[1];
 61     }
 62     int wh=data[j].value<x?1:0;
 63     data[j].ch[wh]=++tot;
 64     make_data(j);
 65     splay(tot);
 66 }
 67 void del(){
 68     int i,wh;
 69     i=get_wh(x);
 70     if(data[i].cnt>1){
 71         data[i].cnt--;data[i].size--;
 72         return;
 73     }
 74     if(data[i].ch[0]*data[i].ch[1]==0&&data[i].ch[0]+data[i].ch[1]!=0){
 75         wh=data[i].ch[0]==0?1:0;
 76         root=data[i].ch[wh];
 77         data[root].fa=0;
 78         cut(i);
 79         return;
 80     }
 81     int old=root,pre=get_wh(las(data[root].value));
 82     splay(pre);
 83     data[data[old].ch[1]].fa=root;data[root].ch[1]=data[old].ch[1];
 84     cut(old);
 85     up(root);
 86 }
 87 int rank(){
 88     int now;
 89     now=get_wh(x);
 90     return data[data[now].ch[0]].size+1;
 91 }
 92 int find(){
 93     int ans=root;
 94     while(!(x>data[data[ans].ch[0]].size&&x<=data[data[ans].ch[0]].size+data[ans].cnt)){
 95         if(x<=data[data[ans].ch[0]].size)
 96             ans=data[ans].ch[0];
 97         else{
 98             x-=data[ans].size;
 99             ans=data[ans].ch[1];
100             x+=data[ans].size;
101         }
102     }
103     return data[ans].value;
104 }
105 int las(int x){
106     int i=get_wh(x);
107     i=data[i].ch[0];
108     while(data[i].ch[1])
109         i=data[i].ch[1];
110 //    splay(i);
111     return data[i].value;
112 }
113 int nex(int x){
114     int i=get_wh(x);
115     i=data[i].ch[1];
116     while(data[i].ch[0])
117         i=data[i].ch[0];
118 //    splay(i);
119     return data[i].value;
120 }
121 void splay(int now){
122     for(int fa=data[now].fa;fa=data[now].fa;roll(now))
123         if(data[fa].fa)
124             roll(get(now)==get(fa)?fa:now);
125     root=now;
126 }
127 void roll(int now){
128     int fa=data[now].fa,fafa=data[fa].fa,wh=get(now);
129     data[fa].ch[wh]=data[now].ch[wh^1];data[data[fa].ch[wh]].fa=fa;
130     data[now].ch[wh^1]=fa;data[fa].fa=now;
131     data[now].fa=fafa;
132     if (fafa)
133         data[fafa].ch[data[fafa].ch[1]==fa]=now;
134     up(fa);up(now);
135 }
136 int get_wh(int x){
137     int i=root;
138     while(data[i].value!=x){
139         if(data[i].value>x)
140             i=data[i].ch[0];
141         else
142             i=data[i].ch[1];
143     }
144     splay(i);
145     return i;
146 }
147 int get(int x){
148     return data[data[x].fa].ch[1]==x;
149 }
150 void cut(int x){
151     data[x].ch[0]=data[x].ch[1]=data[x].cnt=data[x].fa=data[x].size=data[x].value=0;
152 }
153 void make_data(int f){
154     data[tot].fa=f;
155     data[tot].size=data[tot].cnt=1;data[tot].value=x;
156 }
157 void up(int x){
158     data[x].size=data[data[x].ch[0]].size+data[data[x].ch[1]].size+data[x].cnt;
159 }
160 void print(int now){
161     if(!now)return;
162     print(data[now].ch[0]);
163     printf("%d ",data[now].value);
164     print(data[now].ch[1]);
165 }
166 //splay 17.2.20
167 //10
168 //1 5
169 //4 1
170 //1 6
171 //1 7
172 //1 10
173 //1 3
174 //1 4
175 //6 2
176 //1 8
177 //5 9

祝AC

原文地址:https://www.cnblogs.com/nietzsche-oier/p/6419622.html