望各位大佬帮忙纠错!
注释是蒟蒻自己加的。
感谢各位大佬!
#include<bits/stdc++.h>
using namespace std;
#define gen e[0].ch[1]
#define INF 999999999
int m,n,po;
int read(){
int w=0;
char c=getchar();
while (c>'9'||c<'0') c=getchar();
while (c>='0'&&c<='9'){
w=(w<<3)+(w<<1)+(c^48);
c=getchar();
}
return w;
}
struct node{
int v,fa,ch[2],sum,rep;
}e[100005];
int rship(int x){//判断左右子树
return e[e[x].fa].ch[1]==x;
}
void cont(int son,int fa,int rs){//连接父子节点
e[son].fa=fa;
e[fa].ch[rs]=son;
}
void chan(int x){//更新sum值
e[x].sum=e[e[x].ch[0]].sum+e[e[x].ch[1]].sum+e[x].rep;
}
void turn(int x){//旋转
int y=e[x].fa,ygen=e[y].fa,yrship=rship(y),xrship=rship(x);
int B=e[x].ch[xrship^1];
cont(B,y,xrship);cont(y,x,(xrship^1));cont(x,ygen,yrship);
chan(y);chan(x);
}
void splay(int x,int dis){//旋转x至dis
dis=e[dis].fa;
while (e[x].fa!=dis){
int up=e[x].fa;
if (e[up].fa==dis) turn(x);
else if (rship(up)==rship(x)){
turn(up);
turn(x);
}else{
turn(x);
turn(x);
}
}
}
int find(int x){//寻找x在树中的位置
int now=gen;
while (1){
if (e[now].v==x){
splay(now,gen);
return now;
}
int next=x<e[now].v?0:1;
if (!e[now].ch[next]) return 0;
now=e[now].ch[next];
}
}
void addpo(int x,int fa){//加入一个点
n++;
e[n].v=x;
e[n].fa=fa;
e[n].sum=e[n].rep=1;
}
int build(int x){//处理加入一个值
po++;
if (n==0){
gen=1;
addpo(x,0);
}else{
int now=gen;
while (1){
e[now].sum++;
if (x==e[now].v){
e[now].rep++;
return now;
}
int next=x<e[now].v?0:1;
if (!e[now].ch[next]){
addpo(x,now);
e[now].ch[next]=n;
return n;
}
now=e[now].ch[next];
}
}
return 0;
}
void kill(int x){//摧毁节点
e[x].ch[0]=e[x].ch[1]=e[x].fa=e[x].v=e[x].sum=e[x].rep=0;
if (x==n) n--;
}
void push(int x){
int add=build(x);
splay(add,gen);
}
void pop(int x){//删除值
int deal=find(x);
if (!deal) return;
po--;
if (e[deal].rep>1){
e[deal].rep--;
e[deal].sum--;
return;
}
if (!e[deal].ch[0]){
gen=e[deal].ch[1];
e[gen].fa=0;
}else{
int l=e[deal].ch[0];
while (e[l].ch[1]) l=e[l].ch[1];
splay(l,e[deal].ch[0]);
int r=e[deal].ch[1];
cont(r,l,1);cont(l,0,1);
chan(l);
}
kill(deal);
}
int arank(int x){//查询一个数的排名
int ans=0,now=gen;
while (1){
if (e[now].v==x){
ans+=e[e[now].ch[0]].sum+1;
splay(now,gen);
return ans;
}
if (now==0) return 0;
if (x<e[now].v) now=e[now].ch[0];
else{
ans=ans+e[e[now].ch[0]].sum+e[now].rep;
now=e[now].ch[1];
}
}
}
int rerank(int x){//查询一个排名的数
if (x>po) return -INF;
int now=gen;
while (1){
int cha=e[now].sum-e[e[now].ch[1]].sum;
if (x>e[e[now].ch[0]].sum&&x<=cha){
splay(now,gen);
return e[now].v;
}
if (x<cha) now=e[now].ch[0];
else{
x=x-cha;
now=e[now].ch[1];
}
}
}
int low(int x){//查询前驱
int now=gen,ans=-INF;
while (now){
if (e[now].v<x&&e[now].v>ans) ans=e[now].v;
if (x>e[now].v) now=e[now].ch[1];
else now=e[now].ch[0];
}
return ans;
}
int upp(int x){//查询后驱
int now=gen,ans=INF;
while (now){
if (e[now].v>x&&e[now].v<ans) ans=e[now].v;
if (x<e[now].v) now=e[now].ch[0];
else now=e[now].ch[1];
}
return ans;
}
int main(){
m=read();
while (m--){
int opt=read(),x=read();
if (opt==1) push(x);
else if (opt==2) pop(x);
else if (opt==3) printf("%d\n",arank(x));
else if (opt==4) printf("%d\n",rerank(x));
else if (opt==5) printf("%d\n",low(x));
else if (opt==6) printf("%d\n",upp(x));
}
return 0;
}