splay模板题 学习了zyf2000的博客 万分感谢!
#include <stdio.h>
#include <algorithm>
#include <iostream>
using namespace std;
int rt, cnt;
int so[100005][2];
int fa[100005];
int sz[100005];
int cn[100005];
int val[100005];
void clear(int x)
{
sz[x] = fa[x] = so[x][0] = so[x][1] = cn[x] = val[x] = 0;
}
bool ws(int s)
{
return so[fa[s]][1] == s; // 右儿子1 左儿子0
}
void update(int x)
{
if(x)
{
sz[x] = cn[x];
if(so[x][0]) sz[x] += sz[so[x][0]];
if(so[x][1]) sz[x] += sz[so[x][1]];
}
}
void setfa(int s, int f, int d)
{
if(s != 0) fa[s] = f;
if(f != 0) so[f][d] = s;
}
void rot(int x)
{
int f = fa[x]; int ff = fa[f]; int s1 = ws(x); int s2 = ws(f);
int p = so[x][s1 ^ 1];
setfa(p, f, s1);
setfa(f, x, s1 ^ 1);
setfa(x, ff, s2);
update(f);
update(x);
}
void splay(int x)
{
for(; fa[x]; rot(x))
if(fa[fa[x]] && ws(x) == ws(fa[x])) rot(fa[x]);
rt = x;
}
void inser(int v)
{
if(rt == 0)
{
cnt++; so[cnt][0] = so[cnt][1] = fa[cnt] = 0;
val[cnt] = v;
cn[cnt] = 1;
sz[cnt] = 1;
rt = cnt;
return;
}
int now = rt, f = 0;
while(1)
{
if(val[now] == v)
{
cn[now]++; update(now); update(f);
splay(now);
break;
}
f = now;
now = so[now][val[now] < v];
if(now == 0)
{
cnt++;
val[cnt] = v;
cn[cnt] = sz[cnt] = 1;
fa[cnt] = f;
so[f][val[f] < v] = cnt;
so[cnt][1] = so[cnt][0] = 0;
update(f);
splay(cnt);
break;
}
}
}
int find(int v)
{
int now = rt, ans = 0;
while(1)
{
if(v < val[now]) now = so[now][0]; //左
else
{
if(so[now][0]) ans += sz[so[now][0]];
if(v == val[now])
{
splay(now);
return ans + 1;
}
ans += cn[now];
now = so[now][1];
}
}
}
int ffind(int v)
{
int now = rt, ans = 0;
while(1)
{
if(so[now][0] && v <= ans + sz[so[now][0]]) now = so[now][0];
else
{
if(so[now][0]) ans += sz[so[now][0]];
//if(ans >= v) return val[so[now][0]];
ans += cn[now];
if(ans >= v)
{
//splay(now);
return val[now];
}
now = so[now][1];
}
}
}
int pre()
{
int now = so[rt][0];
while(so[now][1]) now = so[now][1];
return now;
}
int nex()
{
int now = so[rt][1];
while(so[now][0]) now = so[now][0];
return now;
}
void del(int x)
{
int no = find(x);
if(cn[rt] > 1)
{
cn[rt]--;
return;
}
if(!so[rt][0] && !so[rt][1]) //没孩子
{
clear(rt);
rt = 0;
return;
}
if(!so[rt][0])
{
int oldrt = rt;
rt = so[rt][1]; fa[rt] = 0;
clear(oldrt);
return;
}
if(!so[rt][1])
{
int oldrt = rt;
rt = so[rt][0]; fa[rt] = 0;
clear(oldrt);
return;
}
// two children
int lrt = pre();
int oldrt = rt;
splay(lrt);
fa[so[oldrt][1]] = lrt;
so[rt][1] = so[oldrt][1];
clear(oldrt);
update(rt);
}
int main()
{
rt = 0;
cnt = 0;
int T;
scanf("%d", &T);
while(T--)
{
int opt, x;
scanf("%d%d", &opt, &x);
switch(opt)
{
case 1: inser(x); break;
case 2: del(x); break;
case 3: printf("%d\n", find(x)); break;
case 4: printf("%d\n", ffind(x)); break;
case 5: inser(x), printf("%d\n", val[pre()]), del(x); break;
case 6: inser(x), printf("%d\n", val[nex()]), del(x); break;
}
}
return 0;
}