Splay的初步学习
具体是啥,qwq
有时间再补吧,贴一下代码;
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cstring> #define MAXN 10086666 using namespace std; int f[MAXN],cnt[MAXN],value[MAXN]; int sons[MAXN][2],sub_size[MAXN]; int root,whole_size; int m,num,be_dealt; inline int read() { int x = 0; int f = 1; char ch = getchar(); while(!isdigit(ch)) { if(ch == '-') f = -1; ch = getchar(); } while(isdigit(ch)) { x = x * 10 + ch - 48; ch = getchar(); } return x * f; } inline void S_clear(int x) { sons[x][0] = sons[x][1] = 0; f[x] = cnt[x] = value[x] = 0; sub_size[x] = 0; } inline bool get_which(int x) { return sons[f[x]][1] == x; } inline void update(int x) { if(x) { sub_size[x] = cnt[x]; if(sons[x][0]) sub_size[x] += sub_size[sons[x][0]]; if(sons[x][1]) sub_size[x] += sub_size[sons[x][1]]; } return ; } inline void rotate(int x) { int father = f[x]; int g_father = f[father]; int which_son = get_which(x); sons[father][which_son] = sons[x][which_son ^ 1]; f[sons[father][which_son]] = father; sons[x][which_son ^ 1] = father; f[father] = x; f[x] = g_father; if(g_father) sons[g_father][sons[g_father][1] == father] = x; update(father); update(x); } inline void splay(int x) { for(int fa;fa = f[x];rotate(x)) if(f[fa]) rotate((get_which(x)) == get_which(fa) ? fa : x); root = x; } inline void insert(int x) { if(!root) { whole_size++; sons[whole_size][0] = sons[whole_size][1] = f[whole_size] = 0; root = whole_size; sub_size[whole_size] = cnt[whole_size]++; value[whole_size] = x; return ; } int now = root; int fa = 0; while(1) { if(x == value[now]) { cnt[now]++; update(now); update(fa); splay(now); break; } fa = now; now = sons[now][value[now] < x]; if(!now) { whole_size++; sons[whole_size][0] = sons[whole_size][1] = 0; f[whole_size] = fa; sub_size[whole_size] = cnt[whole_size] = 1; sons[fa][value[fa] < x] = whole_size; value[whole_size] = x; update(fa); splay(whole_size); break; } } } inline int find_sum(int x) { int now = root; while(1) { if(sons[now][0] && x <= sub_size[sons[now][0]]) now = sons[now][0]; else { int temp = (sons[now][0] ? sub_size[sons[now][0]] : 0) + cnt[now]; if(x <= temp) return value[now]; x -= temp; now = sons[now][1]; } } } inline int find_num(int x) { int now = root; while(1) { if(sons[now][0] && x <= sub_size[sons[now][0]]) now = sons[now][0]; else { int temp = (sons[now][0] ? sub_size[sons[now][0]] : 0) + cnt[now]; if(x <= temp) return value[now]; x -= temp; now = sons[now][1]; } } } inline int find_rank(int x) { int now = root; int ans = 0; while(1) { if(x < value[now]) now = sons[now][0]; else { ans += (sons[now][0] ? sub_size[sons[now][0]] : 0); if(x >= value[now]) { splay(now); return ans + 1; } ans += cnt[now]; now = sons[now][1]; } } } inline int find_pre() { int now = sons[root][0]; while(sons[now][1]) now = sons[now][1]; return now; } inline int find_suffix() { int now = sons[root][1]; while(sons[now][0]) now = sons[now][0]; return now; } inline void my_delete(int x) { int kkk = find_rank(x); if(cnt[root] > 1) { cnt[root]--; update(root); return ; } if(!sons[root][0] && !sons[root][1]) { S_clear(root); root = 0; return ; } if(!sons[root][0]) { int old_root = root; root = sons[root][1]; f[root] = 0; S_clear(old_root); return ; } else if(!sons[root][1]) { int old_root = root; root = sons[root][0]; f[root] = 0; S_clear(old_root); return ; } int left_max = find_pre(); int old_root = root; splay(left_max); sons[root][1] = sons[old_root][1]; f[sons[old_root][1]] = root; S_clear(old_root); update(root); } int main() { scanf("%d",&m); for(int i=1;i<=m;i++) { num = read(); be_dealt = read(); switch(num) { case 1 : insert(be_dealt);break; case 2 : my_delete(be_dealt);break; case 3 : printf("%d\n",find_rank(be_dealt));break; case 4 : printf("%d\n",find_num(be_dealt));break; case 5 : insert(be_dealt);printf("%d\n",value[find_pre()]);my_delete(be_dealt);break; case 6 : insert(be_dealt);printf("%d\n",value[find_suffix()]);my_delete(be_dealt);break; } } return 0; }