[题目链接]
https://www.lydsy.com/JudgeOnline/problem.php?id=1861
[算法]
平衡树
时间复杂度 : O(M log N)
[代码]
#include<bits/stdc++.h> using namespace std; #define MAXN 800010 int n,m; int a[MAXN]; struct Splay { int root , total; int pos[MAXN]; Splay() { root = total = 0; memset(pos,0,sizeof(pos)); } struct Node { int fa; int value,size; int son[2]; } Tree[MAXN]; inline bool get(int x) { return Tree[Tree[x].fa].son[1] == x; } inline void splay(int x) { for (int fa = Tree[x].fa; (fa = Tree[x].fa); rotate(x)) rotate(get(x) == get(fa) ? fa : x); root = x; } inline void push_back(int x) { if (!root) { root = pos[x] = ++total; Tree[root].fa = 0; Tree[root].son[0] = Tree[root].son[1] = 0; Tree[root].value = x; Tree[root].size = 1; return; } int now = root; while (Tree[now].son[1]) now = Tree[now].son[1]; Tree[now].son[1] = pos[x] = ++total; Tree[total].fa = now; Tree[total].son[0] = Tree[total].son[1] = 0; Tree[total].value = x; Tree[total].size = 1; splay(total); } inline void update(int x) { Tree[x].size = 1; Tree[x].size += Tree[Tree[x].son[0]].size; Tree[x].size += Tree[Tree[x].son[1]].size; } inline void rotate(int x) { int f = Tree[x].fa , g = Tree[f].fa; int tmpx = get(x) , tmpf = get(f); if (!f) return; Tree[f].son[tmpx] = Tree[x].son[tmpx ^ 1]; if (Tree[x].son[tmpx ^ 1]) Tree[Tree[x].son[tmpx ^ 1]].fa = f; Tree[x].son[tmpx ^ 1] = f; Tree[f].fa = x; if (g) Tree[g].son[tmpf] = x; Tree[x].fa = g; update(f); update(x); } inline int find(int x) { int now = root; while (now) { if (Tree[now].son[0] && x <= Tree[Tree[now].son[0]].size) now = Tree[now].son[0]; else { int sz = 1; if (Tree[now].son[0]) sz += Tree[Tree[now].son[0]].size; if (x == sz) return now; x -= sz; now = Tree[now].son[1]; } } } inline void erase(int x) { int id = pos[x]; splay(id); if (!Tree[root].son[0] && !Tree[root].son[1]) { Tree[root].size = Tree[root].value = 0; Tree[root].fa = 0; Tree[root].son[0] = Tree[root].son[1] = 0; root = 0; return; } if (!Tree[root].son[0]) { int tmp = root; root = Tree[root].son[1]; Tree[root].fa = 0; Tree[tmp].size = Tree[tmp].value = 0; Tree[tmp].son[0] = Tree[tmp].son[1] = 0; return; } if (!Tree[root].son[1]) { int tmp = root; root = Tree[root].son[0]; Tree[root].fa = 0; Tree[tmp].size = Tree[tmp].value = 0; Tree[tmp].son[0] = Tree[tmp].son[1] = 0; return; } int now = Tree[root].son[0]; while (Tree[now].son[1]) now = Tree[now].son[1]; splay(now); Tree[now].son[1] = Tree[id].son[1]; Tree[Tree[id].son[1]].fa = now; Tree[id].fa = 0; pos[Tree[id].value] = 0; Tree[id].size = Tree[id].value = 0; Tree[id].son[0] = Tree[id].son[1] = 0; update(root); } inline void insert_left(int x) { Tree[root].son[0] = ++total; Tree[total].fa = root; Tree[total].son[0] = Tree[total].son[1] = 0; Tree[total].value = x; Tree[total].size = 1; pos[x] = total; update(root); } inline void insert_right(int x) { Tree[root].son[1] = ++total; Tree[total].fa = root; Tree[total].son[0] = Tree[total].son[1] = 0; Tree[total].value = x; Tree[total].size = 1; pos[x] = total; update(root); } inline void Swap(int x,int y) { int posx = pos[x]; splay(posx); int posy; if (y == -1) { if (!Tree[posx].son[0]) return; posy = Tree[posx].son[0]; while (Tree[posy].son[1]) posy = Tree[posy].son[1]; } else { if (!Tree[posx].son[1]) return; posy = Tree[posx].son[1]; while (Tree[posy].son[0]) posy = Tree[posy].son[0]; } swap(pos[Tree[posx].value],pos[Tree[posy].value]); swap(Tree[posx].value,Tree[posy].value); } inline int ask(int x) { splay(pos[x]); return Tree[Tree[root].son[0]].size; } inline int query(int x) { int ret = find(x); return Tree[ret].value; } } T; int main() { scanf("%d%d",&n,&m); for (int i = 1; i <= n; i++) { scanf("%d",&a[i]); T.push_back(a[i]); } for (int i = 1; i <= m; i++) { char op[10]; int s,t; scanf("%s",op); if (op[0] == 'T') { scanf("%d",&s); if (n == 1) continue; T.erase(s); int x = T.find(1); T.splay(x); T.insert_left(s); } if (op[0] == 'B') { scanf("%d",&s); if (n == 1) continue; T.erase(s); int x = T.find(n - 1); T.splay(x); T.insert_right(s); } if (op[0] == 'I') { scanf("%d%d",&s,&t); if (t == 0) continue; T.Swap(s,t); } if (op[0] == 'A') { scanf("%d",&s); printf("%d ",T.ask(s)); } if (op[0] == 'Q') { scanf("%d",&s); printf("%d ",T.query(s)); } } return 0; }