本蒟蒻首次接触splay,求大佬指点
#include <bits/stdc++.h>
using namespace std;
const int N = 1e4+10;
const long long INF = (1<<31) - 1;
int fa[N], lc[N], rc[N], sz[N], cnt[N], val[N];
int rt, tot;
inline int read ();
bool direction (int );
void Splay (int , int );
inline void inst (int );
void Rotate (int );
inline int Find (int );
inline void inst (int );
inline void join (int , int );
inline void del (int );
inline int rk (int );
inline void update (int );
inline int pre (int );
inline int nxt (int );
inline int Findk (int );
int main () {
int q = read();
while (q --) {
int op = read();
switch (op){
case 1:{
int v = read();
int ans = rk(v);
cout << ans << endl;
break;
}
case 2:{
int x = read();
int ans = Findk(x);
cout << ans << endl;
break;
}
case 3:{
int x = read();
inst(x);
int ans = val[pre(x)];
del(x);
cout << ans << endl;
break;
}
case 4:{
int x = read();
inst(x);
int ans = val[nxt(x)];
del(x);
cout << ans << endl;
break;
}
case 5:{
int x = read();
inst(x);
break;
}
/*
case 1:inst(x);break;
case 2:del(x);break;
case 3:printf ("%d\n", rk(x));break;
case 4:printf ("%d\n", Findk(x));break;
case 5:inst(x);printf("%d/n", val[pre(x)]);del(x);break;
case 6:inst(x);printf("%d\n", val[nxt(x)]);del(x);break;
*/
}
}
return 0;
}
inline int read () {
int x = 0, flag = 1;
char ch = getchar ();
while (!isdigit(ch)) { if (ch == '-') flag = -1; ch = getchar();}
while (isdigit(ch)) { x = (x << 3) + (x << 1) + (ch ^ 48); ch = getchar(); }
return x * flag;
}
bool direction (int x) { //判断链fa[x]-x的方向
return rc[fa[x]] == x;
}
void Splay (int x, int tar) {
while (fa[x]!=tar) {
if (fa[fa[x]] != tar) direction(x) == direction(fa[x]) ? Rotate(fa[x]) : Rotate(x);
Rotate(x);//先转父亲再转自己
}
if (!tar) rt = x;//Splay(x,0)代表x旋转到根节点
return ;
}
inline void inst (int v) {
int u = rt, Fa = 0;
while (u != 0 && v != val[u]) {
Fa = u;
u = (v > val[u] ? rc[u] : lc[u]);
}
if (u) cnt[u] ++;
else {
u = tot++;
if (Fa == 0) rt = u;
else (v > val[u] ? rc[u] : lc[u]) = u;
val[u] = v;
fa[u] = Fa;
cnt[u] = 1;
sz[u] = 1;
}
Splay(u, 0);
return ;
}
void Rotate (int x) {
int y = fa[x], z = fa[y];
int b = (lc[y] == x) ? rc[x] : lc[x];
fa[x] = z;
fa[y] = x;
if (b) fa[b] = y;
if (z) (y == lc[z] ? lc[z] : rc[z]) = x;
if (x == lc[y]) rc[x] = y, lc[y] = b;
else lc[x] = y, rc[y] = b;
return ;
}
inline int Find (int v) {
int x = rt;
while (x) {
if (v == val[x]) break;
if (v > val[x]) x = rc[x];
else x = lc[x];
}
if (x) Splay(x, 0);
return x;
}
inline void join (int u, int v) {
fa[u] = fa[v] = 0;
int w = u;
while (rc[w]) w = rc[w];
Splay(w, 0);
rc[w] = v;
fa[v] = w;
return ;
}
inline void del (int u) {
Splay(u, 0);
if (!lc[u] || !rc[u]) fa[rt = lc[u] + rc[u]] = 0;
else join (lc[u], rc[u]);
lc[u] = rc[u] = 0;
return ;
}
inline int rk (int v) {
int x = Find(v);
return sz[lc[x]] + 1;
}
inline void update (int x) {
sz[x] = sz[lc[x]] + sz[rc[x]];
}
inline int pre (int x) { //前驱
int temp = Find(x);
int u = lc[rt];
if (u == 0) return -INF;
while (rc[u]) u = rc[u];
return u;
}
inline int nxt (int x) { //后驱
int temp = Find(x);
int u = rc[rt];
if (u == 0) return INF;
while (lc[u]) u = lc[u];
return u;
}
inline int Findk (int k) {
int u = rt;
if (sz[u] < k) return -1;//不存在
while (true) {
if (k < sz[lc[u]] + cnt[u]) u = lc[u];
else if (k == sz[lc[u]] + cnt[u]) return u;
else u = rc[u], k -= sz[lc[u]] + cnt[u];
}
}