模板Splay
Posted benjamin-cpp
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了模板Splay相关的知识,希望对你有一定的参考价值。
Splay应该是我目前写过的最长的代码了(188)
#include <iostream>
#include <cstdio>
using namespace std;
//Mystery_Sky
//Splay
#define M 1000100
#define INF 0x3f3f3f3f
#define ll long long
inline int read()
int x=0,f=1; char c=getchar();
while(c<'0'||c>'9') if(c=='-')f=-1;c=getchar();
while(c>='0'&&c<='9') x=x*10+c-'0';c=getchar();
return x*f;
int fa[M], val[M], cnt[M], son[M][2], size[M];
int tot, root, n;
inline void S_clear(int p)
son[p][0] = son[p][1] = fa[p] = size[p] = cnt[p] = val[p] = 0;
inline void update(int p)
if (p)
size[p] = cnt[p];
if (son[p][0]) size[p] += size[son[p][0]];
if (son[p][1]) size[p] += size[son[p][1]];
return ;
inline bool get_which(int p)
return son[fa[p]][1] == p;
inline void Rotate(int p)
int father = fa[p], grfa = fa[father], w_son = get_which(p);
son[father][w_son] = son[p][w_son^1];
fa[son[father][w_son]] = father;
son[p][w_son^1] = father;
fa[father] = p;
fa[p] = grfa;
if(grfa)
son[grfa][son[grfa][1] == father] = p;
update(father);
update(p);
inline void Splay(int p)//关键操作。
for(int f; f = fa[p]; Rotate(p))
if(fa[f]) Rotate((get_which(p) == get_which(f)) ? f : p);
root = p;
inline void insert(int x)
if(!root)
tot++;
son[tot][0] = son[tot][1] = fa[tot] = 0;
root = tot;
size[tot] = cnt[tot]++;
val[tot] = x;
int now = root, f = 0;
while(1)
if(x == val[now])
cnt[now]++;
update(now);
update(f);
Splay(now);
break;
f = now;
now = son[now][val[now]<x];
if(!now)
tot++;
son[tot][0] = son[tot][1] = 0;
fa[tot] = f;
size[tot] = cnt[tot] = 1;
son[f][val[f]<x] = tot;
val[tot] = x;
update(f);
Splay(tot);
break;
inline int query_val(int rank)
int p = root;
while(1)
if(son[p][0] && rank <= size[son[p][0]]) p = son[p][0];
else
int temp = size[son[p][0]] + cnt[p];
if(rank <= temp) return val[p];
rank -= temp;
p = son[p][1];
inline int query_rank(int x)
int p = root, ans = 0;
while(1)
if(x < val[p]) p = son[p][0];
else
ans += size[son[p][0]];
if(x == val[p])
Splay(p);
return ans + 1;
ans += cnt[p];
p = son[p][1];
inline int query_pre()
int p = son[root][0];
while(son[p][1]) p = son[p][1];
return p;
inline int query_next()
int p = son[root][1];
while(son[p][0]) p = son[p][0];
return p;
inline void Delete(int x)
int rank = query_rank(x);
if(cnt[root] > 1)
cnt[root]--;
update(root);
return;
if(!son[root][0] && !son[root][1])
S_clear(root);
root = 0;
return;
if(!son[root][0])
int old_root = root;
root = son[root][1];
fa[root] = 0;
S_clear(old_root);
return;
else if(!son[root][1])
int old_root = root;
root = son[root][0];
fa[root] = 0;
S_clear(old_root);
return;
int lmax = query_pre(), old_root = root;
Splay(lmax);
son[root][1] = son[old_root][1];
fa[son[old_root][1]] = root;
S_clear(old_root);
update(root);
int main()
n = read();
for(int i = 1; i <= n; i++)
int opt = read(), x = read();
if(opt == 1) insert(x);
else if(opt == 2) Delete(x);
else if(opt == 3) printf("%d\n", query_rank(x));
else if(opt == 4) printf("%d\n", query_val(x));
else if(opt == 5) insert(x), printf("%d\n", val[query_pre()]), Delete(x);
else if(opt == 6) insert(x), printf("%d\n", val[query_next()]), Delete(x);
return 0;
以上是关于模板Splay的主要内容,如果未能解决你的问题,请参考以下文章