# bzoj3224 Tyvj 1728 普通平衡树

【题解】

# include <stdio.h>
# include <string.h>
# include <iostream>
# include <algorithm>
// # include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int M = 1e5 + 10;
const int mod = 1e9+7;
const int inf = 2e9 + 10;

# define RG register
# define ST static

struct Splay {
int ch[M][2], fa[M]; int val[M], sz[M], rt, siz, s[M];
inline void set() {
siz = 2; rt = 1;
ch[1][0] = ch[2][0] = ch[2][1] = fa[1] = 0, ch[1][1] = 2; fa[2] = 1;
sz[1] = 2, sz[2] = 1; val[1] = -inf, val[2] = inf; s[1] = s[2] = 1;
}
inline void up(int x) {
if(!x) return ;
sz[x] = s[x] + sz[ch[x][0]] + sz[ch[x][1]];
}
inline void rotate(int x, int &rt) {
int y = fa[x], z = fa[y], ls = ch[y][1] == x, rs = ls^1;
if(rt == y) rt = x;
else ch[z][ch[z][1] == y] = x;
fa[ch[x][rs]] = y, fa[y] = x, fa[x] = z;
ch[y][ls] = ch[x][rs]; ch[x][rs] = y;
up(y); up(x);
}
inline void splay(int x, int &rt) {
while(x != rt) {
int y = fa[x], z = fa[y];
if(y != rt) {
if((ch[z][0] == y) ^ (ch[y][0] == x)) rotate(x, rt);
else rotate(y, rt);
}
rotate(x, rt);
}
}
inline void ins(int &x, int lst, int p) {
if(!x) {
x = ++siz; fa[x] = lst; ch[x][0] = ch[x][1] = 0; sz[x] = 1;
val[x] = p; s[x] = 1;
return;
}
if(p == val[x]) {
s[x] ++; sz[x] ++;
return ;
}
if(p < val[x]) ins(ch[x][0], x, p);
else ins(ch[x][1], x, p);
up(x);
}
inline void INS(int p) {
ins(rt, 0, p);
splay(siz, rt);
}

inline int find(int x, int p) {
if(!x) return inf;
if(val[x] == p) return x;
if(p < val[x]) return find(ch[x][0], p);
else return find(ch[x][1], p);
}

inline int gpre(int x, int p) {
if(!x) return inf;
if(val[x] < p) {
int y = gpre(ch[x][1], p);
if(y != inf) return y;
else return x;
} else return gpre(ch[x][0], p);
}
inline int gsuf(int x, int p) {
if(!x) return inf;
if(val[x] > p) {
int y = gsuf(ch[x][0], p);
if(y != inf) return y;
else return x;
} else return gsuf(ch[x][1], p);
}

inline int pre(int x) {
while(ch[x][1]) x = ch[x][1];
return x;
}
inline int suf(int x) {
while(ch[x][0]) x = ch[x][0];
return x;
}

inline void DEL(int p) {
int x = find(rt, p);
splay(x, rt);
if(s[x] > 1) {
--s[x]; up(x);
return ;
}
int y = pre(ch[x][0]); splay(y, ch[x][0]);
rt = y; fa[y] = 0; ch[y][1] = ch[x][1]; fa[ch[x][1]] = y;
up(y); fa[x] = ch[x][0] = ch[x][1] = s[x] = sz[x] = 0;
}

inline void PRE(int p) {
int x = find(rt, p);
if(x == inf) {
int y = gpre(rt, p);
splay(y, rt);
printf("%d\n", val[y]);
return ;
}
splay(x, rt);
int y = pre(ch[x][0]);
printf("%d\n", val[y]);
}

inline void SUF(int p) {
int x = find(rt, p);
if(x == inf) {
int y = gsuf(rt, p);
splay(y, rt);
printf("%d\n", val[y]);
return ;
}
splay(x, rt);
int y = suf(ch[x][1]);
printf("%d\n", val[y]);
}

inline void getrank(int p) {
int x = find(rt, p); splay(x, rt);
printf("%d\n", sz[ch[x][0]]);
}

inline int findrk(int x, int p) {
if(sz[ch[x][0]] + 1 <= p && p <= sz[ch[x][0]] + s[x]) return x;
if(sz[ch[x][0]] + 1 > p) return findrk(ch[x][0], p);
else return findrk(ch[x][1], p - s[x] - sz[ch[x][0]]);
}

inline void prank(int x) {
int y = findrk(rt, x+1); splay(y, rt);
printf("%d\n", val[y]);
}
}T;

int main() {
int Q, op, x; cin >> Q; T.set();
while(Q--) {
scanf("%d%d", &op, &x);
if(op == 1) T.INS(x);
else if(op == 2) T.DEL(x);
else if(op == 3) T.getrank(x);
else if(op == 4) T.prank(x);
else if(op == 5) T.PRE(x);
else T.SUF(x);
}
return 0;
}
View Code

posted @ 2017-07-16 11:12  Galaxies  阅读(245)  评论(0编辑  收藏  举报