嗯没错就是一个平衡树的板子,然而就是这个板子我调了一下午没有调出来最后还是麻烦了CJQ大佬花了一晚上帮我调试。
感谢!
参考代码:
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define SG string
#define DB double
using namespace std;
const int Max=2e5+5;
int N,Ans;
int Cnt=1,Root,Fa[Max],Key[Max],Num[Max],Size[Max],CH[Max][2];
inline int Read(){
int X=0;char CH=getchar();bool F=0;
while(CH>'9'||CH<'0'){if(CH=='-')F=1;CH=getchar();}
while(CH>='0'&&CH<='9'){X=(X<<1)+(X<<3)+CH-'0';CH=getchar();}
return F?-X:X;
}
inline void Write(int X){
if(X<0)X=-X,putchar('-');
if(X>9)Write(X/10);
putchar(X%10+48);
}
int NewNode(int _Key,int _Fa){
Key[++Cnt]=_Key;Fa[Cnt]=_Fa;
Num[Cnt]=Size[Cnt]=1;CH[Cnt][0]=CH[Cnt][1]=0;
return Cnt;
}
void PushUp(int X){
Size[X]=Size[CH[X][0]]+Size[CH[X][1]]+Num[X];
}
void Rotate(int X,int P){
int Y=Fa[X];
CH[Y][!P]=CH[X][P];
Fa[CH[X][P]]=Y;Fa[X]=Fa[Y];
if(Fa[X]){
CH[Fa[X]][CH[Fa[X]][1]==Y]=X;
}CH[X][P]=Y;Fa[Y]=X;
PushUp(Y);PushUp(X);
}
void Splay(int X,int To){
while(Fa[X]!=To){
if(Fa[Fa[X]]==To){
Rotate(X,CH[Fa[X]][0]==X);
} else {
int Y=Fa[X],Z=Fa[Y];
int P=(CH[Z][0]==Y);
if(CH[Y][P]==X){
Rotate(X,!P),Rotate(X,P);
} else {
Rotate(Y,P),Rotate(X,P);
}
}
}
if(To==0){
Root=X;
}
}
int Find(int _Key){
if(!Root){
return 0;
}
int X=Root;
while(X){
if(Key[X]==_Key){
break;
}X=CH[X][_Key>Key[X]];
}
if(X){
Splay(X,0);
}
return X;
}
void Insert(int _Key){
if(!Root){
Root=NewNode(_Key,0);
} else {
int X=Root,Y=0;
while(X){
Y=X;
if(Key[X]==_Key){
Num[X]++;
Size[X]++;
break;
}Size[X]++;
X=CH[X][_Key>Key[X]];
}
if(!X){
X=CH[Y][_Key>Key[Y]]=NewNode(_Key,Y);
}Splay(X,0);
}
}
void Delete(int _Key){
int X=Find(_Key);
if(!X){
return ;
}
if(Num[X]>1){
Num[X]--;
PushUp(X);return;
}
int Y=CH[X][0];
while(CH[Y][1]){
Y=CH[Y][1];
}
int Z=CH[X][1];
while(CH[Z][0]){
Z=CH[Z][0];
}
if(!Y&&!Z){
Root=0;return;
}
if(!Y){
Splay(Z,0);
CH[Z][0]=0;PushUp(Z);return ;
}
if(!Z){
Splay(Y,0);
CH[Y][1]=0;PushUp(Y);return ;
}
Splay(Y,0);Splay(Z,Y);
CH[Z][0]=0;PushUp(Z);PushUp(Y);
}
int GetRank(int K,int _Key){
if(K==0){
return 0;
}
if(_Key==Key[K]){
return Size[CH[K][0]]+1;
} else if (_Key>Key[K]){
return Size[CH[K][0]]+Num[K]+GetRank(CH[K][1],_Key);
} else {
return GetRank(CH[K][0],_Key);
}
}
int GetKth(int K){
if(!Root||K>Size[Root]){
return 0;
}
int X=Root;
while(X){
if(K>=Size[CH[X][0]]+1&&K<=Size[CH[X][0]]+Num[X]){
break;
}
if(K>Size[CH[X][0]]+Num[X]){
K-=(Size[CH[X][0]]+Num[X]);
X=CH[X][1];
} else {
X=CH[X][0];
}
}
Splay(X,0);
return Key[X];
}
int Pre(int _Key){
Insert(_Key);
int X=CH[Root][0];
while(CH[X][1]){
X=CH[X][1];
}Splay(X,0);
Delete(_Key);
return Key[X];
}
int Suc(int _Key){
Insert(_Key);
int X=CH[Root][1];
while(CH[X][0]){
X=CH[X][0];
}
Splay(X,0);
Delete(_Key);
return Key[X];
}
int main(){
int I,J,K;
N=Read();
for(I=1;I<=N;I++){
int X=Read(),Y=Read();
if(X==1){
Insert(Y);
} else if (X==2){
Delete(Y);
} else if (X==3){
Write(GetRank(Root,Y)),putchar('\n');
} else if (X==4){
Write(GetKth(Y)),putchar('\n');
} else if (X==5){
Write(Pre(Y)),putchar('\n');
}
else {
Write(Suc(Y)),putchar('\n');
}
}
return 0;
}