题目
题意
中文体面,题意就不写了
思路
s p l a y splay splay 模板题,实现插入、删除、查询等操作
代码
int ch[maxn][2], pre[maxn], key[maxn], sz[maxn], cnt[maxn];
int root, tot;
void print(int u){
// printf("%d: ls:%d rs:%d cnt:%d minn:%d maxx:%d\n", key[u], key[ch[u][0]],
// key[ch[u][1]], cnt[u], minn[u], maxx[u]);
if(ch[u][0]) print(ch[u][0]);
if(ch[u][1]) print(ch[u][1]);
}
void init(){
root = tot = 0;
ch[0][0] = ch[0][1] = pre[0] = key[0] = sz[0] = 0;
}
int judge(int x){
return ch[pre[x]][1]==x;
}
void push_up(int x) {
if(!x) return ;
sz[x] = sz[ch[x][0]] + sz[ch[x][1]] + cnt[x];
// minn[x] = min(val[x], min(minn[ch[x][0]], minn[ch[x][1]]));
// maxx[x] = max(val[x], max(maxx[ch[x][0]], maxx[ch[x][1]]));
// printf("minn: x:%d ls:%d rs:%d\n", val[x], minn[ch[x][0]], minn[ch[x][1]]);
}
void setson(int x, int fa, int k) {
if(x) pre[x] = fa;
if(fa) {
ch[fa][k] = x;
push_up(fa);
}
else root = x;
}
void rotate(int x) {
int f = pre[x], ff = pre[pre[x]];
int sx = judge(x), sf = judge(f);
int p = ch[x][!sx];
setson(p, f, sx);
setson(x, ff, sf);
setson(f, x, !sx);
push_up(f);
push_up(x);
}
void splay(int x, int goal) { //0-root
while(pre[x] != goal){
if(pre[pre[x]] == goal)
rotate(x);
else {
int f = pre[x];
if(judge(x) == judge(f)) rotate(f);
else rotate(x);
rotate(x);
}
}
if(!goal) root = x;
}
int found(int x, int val) {
if(!x) return 0;
if(val == key[x]) {
splay(x, 0);
return x;
}
return val < key[x] ? found(ch[x][0], val) : found(ch[x][1], val);
}
void ins(int &x, int val, int fa){
if(!x) {
x = ++tot;
key[x] = val; pre[x] = fa;
ch[x][0] = ch[x][1] = 0;
sz[x] = cnt[x] = 1;
}
else {
int t = x;
if(val == key[t]) cnt[x]++;
else val < key[t] ? ins(ch[t][0], val, t) : ins(ch[t][1], val, t);
push_up(t);
}
}
void insert(int val){
ins(root, val, 0);
splay(tot, 0);
}
void del() { // delete root
if(cnt[root] > 1){
--cnt[root];
--sz[root];
return;
}
if(!ch[root][0]){
pre[ch[root][1]] = 0;
root = ch[root][1];
}
else{
int cur = ch[root][0];
while(ch[cur][1]) cur = ch[cur][1];
splay(cur, root);
ch[cur][1] = ch[root][1];
root = cur;
pre[cur] = 0;
if(ch[root][1]) pre[ch[root][1]] = root;
push_up(root);
}
}
void delnode(int val){
int k = found(root, val);
if(k) del();
}
int Kth(int u, int k){
if(!u) return 0;
if(k <= sz[ch[u][0]]) return Kth(ch[u][0], k);
if(k > sz[ch[u][0]] + cnt[u]) return Kth(ch[u][1], k-sz[ch[u][0]]-cnt[u]);
return key[u];
}
int Rank(int u, int val) {
if(!u) return 0;
if(key[u] == val) return sz[ch[u][0]] + 1;
if(key[u] < val) return sz[ch[u][0]] + cnt[u] + Rank(ch[u][1], val);
return Rank(ch[u][0], val);
}
int pred(int u, int val) {
if(!u) return inf;
if(val <= key[u]) return pred(ch[u][0], val);
int ans = pred(ch[u][1], val);
if(ans == inf) ans = key[u];
return ans;
}
int succ(int u, int val){
if (!u) return inf;
if(val >= key[u]) return succ(ch[u][1], val);
int ans = succ(ch[u][0], val);
if(ans == inf) ans = key[u];
return ans;
}