BZOJ 1861 书架
平衡树
随便一个splay搞搞就行啦~~
需要一个pos数组来查找书编号为i的节点号
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define full(a, b) memset(a, b, sizeof a)
using namespace std;
typedef long long ll;
inline int lowbit(int x){ return x & (-x); }
inline int read(){
int X = 0, w = 0; char ch = 0;
while(!isdigit(ch)) { w |= ch == '-'; ch = getchar(); }
while(isdigit(ch)) X = (X << 3) + (X << 1) + (ch ^ 48), ch = getchar();
return w ? -X : X;
}
inline int gcd(int a, int b){ return a % b ? gcd(b, a % b) : b; }
inline int lcm(int a, int b){ return a / gcd(a, b) * b; }
template<typename T>
inline T max(T x, T y, T z){ return max(max(x, y), z); }
template<typename T>
inline T min(T x, T y, T z){ return min(min(x, y), z); }
template<typename A, typename B, typename C>
inline A fpow(A x, B p, C lyd){
A ans = 1;
for(; p; p >>= 1, x = 1LL * x * x % lyd)if(p & 1)ans = 1LL * x * ans % lyd;
return ans;
}
const int N = 80005;
int n, m, tot, root, ch[N][2], fa[N], pos[N], size[N], val[N], a[N];
int init(int v, int f){
++tot;
val[tot] = v, size[tot] = 1, pos[v] = tot, fa[tot] = f;
ch[tot][0] = ch[tot][1] = 0;
return tot;
}
void push_up(int x){
int l = ch[x][0], r = ch[x][1];
size[x] = size[l] + size[r] + 1;
pos[val[x]] = x;
}
void rotate(int x){
int y = fa[x], z = fa[y], p = (ch[y][1] == x) ^ 1;
ch[y][p^1] = ch[x][p], fa[ch[x][p]] = y;
ch[z][ch[z][1] == y] = x, fa[x] = z;
ch[x][p] = y, fa[y] = x;
push_up(y), push_up(x);
}
void splay(int x, int goal){
if(x == goal) return;
while(fa[x] != goal){
int y = fa[x], z = fa[y];
if(z != goal){
(ch[y][0] == x) ^ (ch[z][0] == y) ? rotate(x) : rotate(y);
}
rotate(x);
}
push_up(x);
if(goal == 0) root = x;
}
void top(int x){
splay(pos[x], 0);
if(!ch[root][0]) return;
if(!ch[root][1]){
ch[root][1] = ch[root][0], ch[root][0] = 0;
return;
}
int cur = ch[root][1];
while(ch[cur][0]) cur = ch[cur][0];
ch[cur][0] = ch[root][0], fa[ch[root][0]] = cur;
ch[root][0] = 0;
splay(ch[cur][0], 0);
}
void bottom(int x){
splay(pos[x], 0);
if(!ch[root][1]) return;
if(!ch[root][0]){
ch[root][0] = ch[root][1], ch[root][1] = 0;
return;
}
else{
int cur = ch[root][0];
while(ch[cur][1]) cur = ch[cur][1];
ch[cur][1] = ch[root][1], fa[ch[root][1]] = cur;
ch[root][1] = 0;
splay(ch[cur][1], 0);
}
}
void insert(int x, int t){
splay(pos[x], 0);
if(!t) return;
int p = t == 1 ? 1 : 0;
int cur = ch[root][p];
while(ch[cur][p^1]) cur = ch[cur][p^1];
int tmp = pos[x], to = val[cur];
swap(val[tmp], val[cur]);
swap(pos[x], pos[to]);
splay(ch[root][p], 0);
}
int ask(int x){
splay(pos[x], 0);
return size[ch[root][0]];
}
int query(int x){
int cur = root, p = size[ch[root][0]];
while(1){
if(x > p + 1){
cur = ch[cur][1];
x -= p + 1;
}
else{
if(p >= x) cur = ch[cur][0];
else return val[cur];
}
p = size[ch[cur][0]];
}
}
int buildTree(int x, int l, int r){
if(l > r) return 0;
int mid = (l + r) >> 1;
int p = init(a[mid], x);
ch[p][0] = buildTree(p, l, mid - 1);
ch[p][1] = buildTree(p, mid + 1, r);
push_up(p);
return p;
}
int main(){
n = read(), m = read();
for(int i = 1; i <= n; i ++) a[i] = read();
root = buildTree(0, 1, n);
while(m --){
char opt[20]; scanf("%s", opt);
int s = read();
if(opt[0] == 'T') top(s);
else if(opt[0] == 'B') bottom(s);
else if(opt[0] == 'I') { int x = read(); insert(s, x); }
else if(opt[0] == 'A') printf("%d\n", ask(s));
else if(opt[0] == 'Q') printf("%d\n", query(s));
}
return 0;
}