#include <cstdio>
#include <cstdlib>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
struct item {int val, id;};
bool operator < (item A, item B) {
if(A.val != B.val) return A.val < B.val;
return A.id < B.id;
}
bool operator == (item A, item B) {
return A.val==B.val && A.id==B.id;
}
const int maxn = (500000 + 6)*2;
namespace treap {
int ch[maxn][2], rnd[maxn], siz[maxn]; item key[maxn]; int ncnt;
queue<int> Q;
void maintain(int x) {
siz[x] = 1 + siz[ch[x][0]] + siz[ch[x][1]];
}
int newnode() {
if(!Q.empty()) {
int x = Q.front(); Q.pop();
ch[x][0] = ch[x][1] = rnd[x] = siz[x] = 0; key[x] = (item){0, 0};
return x;
}
return ++ ncnt;
}
void rotate(int& x, int d) {
int k = ch[x][d^1]; ch[x][d^1] = ch[k][d]; ch[k][d] = x;
maintain(x); x = k; maintain(k);
}
void insert(int& x, item v) {
if(x == 0) {
x = newnode(); rnd[x] = rand(); siz[x] = 1; key[x] = v;
return;
}
int d = v < key[x] ? 0 : 1; insert(ch[x][d], v);
maintain(x);
if(rnd[x] > rnd[ch[x][d]]) rotate(x, d^1);
}
int rnk(int x, item v) {
if(x == 0) return 1;
int lsiz = 1 + siz[ch[x][0]];
if(v == key[x]) return lsiz;
if(v < key[x]) return rnk(ch[x][0], v);
else return rnk(ch[x][1], v) + lsiz;
}
item kth(int x, int k) {
if(x==0 || k<=0 || k>siz[x])
return k<=0 ? (item){-2147483647, 0} : (item){2147483647, 0};
int lsiz = 1 + siz[ch[x][0]];
if(lsiz == k) return key[x];
if(k < lsiz) return kth(ch[x][0], k);
else return kth(ch[x][1], k-lsiz);
}
int LSIZ(int x) {return 1 + siz[ch[x][0]];}
void erase(int& x, int k) {
if(x == 0) return; /// 删除元素时一定要特判检测是否相等
int lsiz = 1 + siz[ch[x][0]];
if(lsiz == k) {
if(ch[x][0]==0 || ch[x][1]==0) {
int tmp = x; x = ch[x][0] + ch[x][1]; Q.push(tmp);
ch[tmp][0] = ch[tmp][1] = siz[tmp] = rnd[tmp] = 0;
key[tmp] = (item){0, 0};
}else {
if(rnd[ch[x][0]] > rnd[ch[x][1]]) {
rotate(x, 0); erase(ch[x][0], LSIZ(ch[x][0]));
}else {
rotate(x, 1); erase(ch[x][1], LSIZ(ch[x][1]));
}
maintain(x);
}
return;
}else {
if(k < lsiz) erase(ch[x][0], k);
else erase(ch[x][1], k-lsiz);
maintain(x);
}
}
}
int root = 0, V[maxn], OPT[maxn], X[maxn], ANS[maxn];
namespace tree {
vector<int> nxt[maxn];
void addedge(int f, int t) {nxt[f].push_back(t);}
void dfs(int x) {
bool delsuc = 0; /// 记录删除操作是否成功
if(OPT[x]) { /// 有操作
if(OPT[x] == 1) { /// 插入一个元素
treap::insert(root, (item){X[x], x});
}else if(OPT[x] == 2) { /// 删除一个元素
int rnk = treap::rnk(root, (item){X[x], 0}); /// 查询这个元素的排名
int get = treap::kth(root, rnk).val; /// 得到这个元素(可能为+-inf)
if(get == X[x]) { /// 可以删除
treap::erase(root, rnk); delsuc = 1;
}
}else if(OPT[x] == 3) { /// 查排名
ANS[x] = treap::rnk(root, (item){X[x], 0});
}else if(OPT[x] == 4) { /// 查第k大
ANS[x] = treap::kth(root, X[x]).val;
}else if(OPT[x] == 5) { /// prev
int rnk = treap::rnk(root, (item){X[x], 0}) - 1;
int get = treap::kth(root, rnk).val;
ANS[x] = get;
}else if(OPT[x] == 6) { /// next
int rnk = treap::rnk(root, (item){X[x], 0x7f7f7f7f});
int get = treap::kth(root, rnk).val;
ANS[x] = get;
}
}
for(int i = 0; i < (int)nxt[x].size(); i ++) {
int t = nxt[x][i]; dfs(t); /// 递归计算
}
if(OPT[x] == 1) { /// 回滚插入操作
int rnk = treap::rnk(root, (item){X[x], 0}); /// 一定有
treap::erase(root, rnk);
}
if(OPT[x]==2 && delsuc) {
treap::insert(root, (item){X[x], x});
}
}
}
int main() {
//freopen("nontime.in", "r", stdin);
int n; scanf("%d", &n);
for(int i = 1; i <= n; i ++) {
scanf("%d%d%d", &V[i], &OPT[i], &X[i]);
tree::addedge(V[i], i);
}
tree::dfs(0);
for(int i = 1; i <= n; i ++) {
if(OPT[i]>=3) {
printf("%d\n", ANS[i]);
}
}
return 0;
}
# 将上面一份代码的风格改为以下代码的风格
#include<bits/stdc++.h>
using namespace std;
const int INF=1e9;
int n,ch[1000010][2],val[1000010],dat[1000010],size[1000010],cnt[1000010],tot,root;
int New(int v){
val[++tot]=v;
dat[tot]=rand();
size[tot]=1;
cnt[tot]=1;
return tot;
}
void pushup(int id){
size[id]=size[ch[id][0]]+size[ch[id][1]]+cnt[id];
}
void build(){
root=New(-INF),ch[root][1]=New(INF);
pushup(root);
}
void Rotate(int &id,int d){
int temp=ch[id][d^1];
ch[id][d^1]=ch[temp][d];
ch[temp][d]=id;
id=temp;
pushup(ch[id][d]),pushup(id);
}
void charu(int &id,int v){
if(!id){
id=New(v);
return ;
}
if(v==val[id])cnt[id]++;
else {
int d=v<val[id]?0:1;
charu(ch[id][d],v);
if(dat[id]<dat[ch[id][d]])Rotate(id,d^1);
}
pushup(id);
}
void shanchu(int &id,int v){
if(!id)return ;
if(v==val[id]){
if(cnt[id]>1){
cnt[id]--,pushup(id);
return ;
}
if(ch[id][0]||ch[id][1]){
if(!ch[id][1]||dat[ch[id][0]]>dat[ch[id][1]]){
Rotate(id,1),shanchu(ch[id][1],v);
}else Rotate(id,0),shanchu(ch[id][0],v);
pushup(id);
}else id=0;
return ;
}
v<val[id]?shanchu(ch[id][0],v):shanchu(ch[id][1],v);
pushup(id);
}
int xiao(int id,int v){
if(!id)return 1;
if(v==val[id])return size[ch[id][0]]+1;
else if(v<val[id])return xiao(ch[id][0],v);
else return size[ch[id][0]]+cnt[id]+xiao(ch[id][1],v);
}
int paimin(int id,int rank){
if(!id)return INF;
if(rank<=size[ch[id][0]])return paimin(ch[id][0],rank);
else if(rank<=size[ch[id][0]]+cnt[id])return val[id];
else return paimin(ch[id][1],rank-size[ch[id][0]]-cnt[id]);
}
int qianqu(int v){
int id=root,pre;
while(id){
if(val[id]<v)pre=val[id],id=ch[id][1];
else id=ch[id][0];
}
return pre;
}
int houji(int v){
int id=root,next;
while(id){
if(val[id]>v)next=val[id],id=ch[id][0];
else id=ch[id][1];
}
return next;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
build();
cin>>n;
int opt,x;
for(int i=1;i<=n;i++){
cin>>opt>>x;
if(opt==1)charu(root,x);
else if(opt==2)shanchu(root,x);
else if(opt==3)cout<<xiao(root,x)-1<<'\n';
else if(opt==4)cout<<paimin(root,x+1)<<'\n';
else if(opt==5)cout<<qianqu(x)<<'\n';
else if(opt==6)cout<<houji(x)<<'\n';
}
return 0;
}