正题
评测记录:https://www.luogu.org/recordnew/lists?uid=SSL_WYC_zombieeeeee&pid=P3369&status=&sort=0
题目大意
要求支持查询一个数字的排名,查询该排名的数字,插入数字,删除数字,求前驱后继。
解题思路
有旋Treap不解释。
c o d e code code
#include<cstdio>
#include<algorithm>
#define INF 2147483647/3
#define N 100010
using namespace std;
int n,root;
struct Treap_node{
int l[N],r[N];
int val[N],dat[N];
int cnt[N],size[N];
int tot;
int New(int new_val){
val[++tot]=new_val;
dat[tot]=rand();
cnt[tot]=size[tot]=1;
return tot;
}
void Updata(int p){
size[p]=size[l[p]]+size[r[p]]+cnt[p];
}
void Build(){
New(-INF);New(INF);
root=1;r[1]=2;
Updata(root);
}
int GetRankByVal(int p,int num){
if(p==0) return 0;
if(num==val[p]) return size[l[p]]+1;
if(num<val[p]) return GetRankByVal(l[p],num);
return GetRankByVal(r[p],num)+size[l[p]]+cnt[p];
}
int GetValByRank(int p,int rank){
if (p==0) return INF;
if(size[l[p]]>=rank) return GetValByRank(l[p],rank);
if(size[l[p]]+cnt[p]>=rank) return val[p];
return GetValByRank(r[p],rank-size[l[p]]-cnt[p]);
}
void zig(int &p){
int q=l[p];
l[p]=r[q];r[q]=p;p=q;
Updata(r[p]);Updata(p);
}
void zag(int &p){
int q=r[p];
r[p]=l[q];l[q]=p;p=q;
Updata(l[p]);Updata(p);
}
void Insert(int &p,int num){
if(p==0){
p=New(num);
return;
}
if(num==val[p]){
cnt[p]++;Updata(p);
return;
}
if(num<val[p]){
Insert(l[p],num);
if(dat[p]<dat[l[p]]) zig(p);
}
else{
Insert(r[p],num);
if(dat[p]<dat[r[p]]) zag(p);
}
Updata(p);
}
int GetPre(int num){
int ans=1;
int p=root;
while(p){
if(num==val[p]){
if(l[p]>0){
p=l[p];
while(r[p]>0) p=r[p];
ans=p;
}
break;
}
if(val[p]<num&&val[p]>val[ans]) ans=p;
p=num<val[p]?l[p]:r[p];
}
return val[ans];
}
int GetNext(int num){
int ans=2;
int p=root;
while(p){
if(num==val[p]){
if(r[p]>0){
p=r[p];
while(l[p]>0) p=l[p];
ans=p;
}
break;
}
if(val[p]>num&&val[p]<val[ans]) ans=p;
p=num<val[p]?l[p]:r[p];
}
return val[ans];
}
void Remove(int &p,int num){
if(p==0) return;
if(num==val[p]){
if(cnt[p]>1){
cnt[p]--;Updata(p);
return;
}
if(l[p]||r[p]){
if(r[p]==0||dat[l[p]]>dat[r[p]])
zig(p),Remove(r[p],num);
else
zag(p),Remove(l[p],num);
Updata(p);
}
else p=0;
return;
}
num<val[p]?Remove(l[p],num):Remove(r[p],num);
Updata(p);
}
}a;
int main()
{
a.Build();
scanf("%d",&n);
while(n--){
int opt,x;
scanf("%d%d",&opt,&x);
switch(opt){
case 1:
a.Insert(root,x);
break;
case 2:
a.Remove(root,x);
break;
case 3:
printf("%d\n",a.GetRankByVal(root,x)-1);
break;
case 4:
printf("%d\n",a.GetValByRank(root,x+1));
break;
case 5:
printf("%d\n",a.GetPre(x));
break;
case 6:
printf("%d\n",a.GetNext(x));
break;
}
}
}