RT, WA on 第15个点7000多行,不知道哪里有问题。。。
#include <bits/stdc++.h>
using namespace std;
#define N 600010
#define ll long long
#define int long long
const int INF = 2147483647;
template <class T>
inline void read(T& a){
T x = 0, s = 1;
char c = getchar();
while(!isdigit(c)){
if(c == '-') s = -1;
c = getchar();
}
while(isdigit(c)){
x = x * 10 + (c ^ '0');
c = getchar();
}
a = x * s;
return ;
}
int n;
int root[N];
struct Treap{
struct node{
int siz, val, pri;
int lson, rson;
} t[N * 50];
int tot;
Treap(int tot = 0){
this->tot = tot;
return ;
}
int build(int key = 0){
tot++;
t[tot].val = key;
t[tot].pri = rand() * rand() % (ll)1e9;
t[tot].lson = t[tot].rson = 0;
t[tot].siz = 1;
return tot;
}
inline void pushup(int now){
t[now].siz = t[t[now].lson].siz + t[t[now].rson].siz + 1;
return ;
}
void split(int now, int key, int &x, int &y){
if(!now){
x = y = 0;
return ;
}
if(key >= t[now].val){
x = build();
t[x] = t[now];
split(t[x].rson, key, t[x].rson, y);
pushup(x);
}
else{
y = build();
t[y] = t[now];
split(t[y].lson, key, x, t[y].lson);
pushup(y);
}
return ;
}
int merge(int x, int y){
if(!x || !y) return x + y;
if(t[x].pri > t[y].pri){
int now = build(); // merge 是否新建节点取决于版本间的 merge 与 split 操作是否成对出现。
t[now] = t[x]; // 如果成对出现,此处新不新建均可。
t[now].rson = merge(t[now].rson, y);
pushup(now);
return now;
}
else{
int now = build();
t[now] = t[y];
t[now].lson = merge(x, t[now].lson);
pushup(now);
return now;
}
}
void insert(int key, int k){
int x, y;
split(root[k], key - 1, x, y);
root[k] = merge(x, merge(build(key), y));
return ;
}
void del(int key, int k){
int x, y, z;
split(root[k], key - 1, x, z);
split(z, key, y, z);
if(y){
y = merge(t[y].lson, t[y].rson);
}
root[k] = merge(merge(x, y), z);
return ;
}
int find_kth(int now, int k){
if(!now) return -INF;
if(t[t[now].lson].siz + 1 == k) return t[now].val; // 这句话一定放最前面,先判断。否则会一路下去
else if(t[t[now].lson].siz >= k) return find_kth(t[now].lson, k);
else return find_kth(t[now].rson, k - t[t[now].lson].siz - 1);
}
int find_rank(int key, int k){
int x, y, ans;
split(root[k], key - 1, x, y);
ans = t[x].siz + 1;
root[k] = merge(x, y);
return ans;
}
int get_pre(int key, int k){
int x, y, ans, now;
split(root[k], key - 1, x, y);
now = x;
while(t[now].rson) now = t[now].rson;
ans = x ? t[now].val : -INF;
root[k] = merge(x, y);
return ans;
}
int get_next(int key, int k){
int x, y, ans, now;
split(root[k], key + 1, x, y);
now = y;
while(t[now].lson) now = t[now].lson;
ans = y ? t[now].val : INF;
root[k] = merge(x, y);
return ans;
}
void dfs(int now){
if(!now) return ;
dfs(t[now].lson);
printf("%d ", t[now].val);
dfs(t[now].rson);
return ;
}
} tree;
signed main(){
srand(time(0));
freopen("hh.txt", "r", stdin);
freopen("out.txt", "w", stdout);
read(n);
for(int i = 1; i <= n; i++){
int v, opt, x;
read(v), read(opt), read(x);
root[i] = root[v];
switch (opt){
case 1:
tree.insert(x, i);
break;
case 2:
tree.del(x, i);
break;
case 3:
printf("%d\n", tree.find_rank(x, i));
break;
case 4:
printf("%d\n", tree.find_kth(root[i], x));
break;
case 5:
printf("%d\n", tree.get_pre(x, i));
break;
case 6:
printf("%d\n", tree.get_next(x, i));
break;
}
// printf("root: %d ", root[i]);
// tree.dfs(root[i]); printf("\n");
// printf("opt: %d\n", opt);
}
return 0;
}