题目就不说了,平衡树裸题。
为什么我的所有平衡树都比别人的慢上一大截啊。
#include <cstdio>
using namespace std;
const int N=100002;
const double alpha=0.721,sin=0.5;
inline char tc(void){
static char fl[N],*A=fl,*B=fl;
return A==B&&(B=(A=fl)+fread(fl,1,N,stdin),A==B)?EOF:*A++;
}
inline int read(void){
int a=0,f=1;static char c;
while((c=tc())<'0'||c>'9')c=='-'?f=-1:0;
while(c>='0'&&c<='9')a=a*10+c-'0',c=tc();
return a*f;
}
inline int max(int a,int b){
return a>b?a:b;
}
int v[N],sz[N],ls[N],rs[N],cnt[N],exist[N],n,root,tot,que[N],tque,*sgt;
inline void update(int x){
sz[x]=exist[x]+sz[ls[x]]+sz[rs[x]],
cnt[x]=1+cnt[ls[x]]+cnt[rs[x]];
return ;
}
void dfs(int x){
if(ls[x])dfs(ls[x]);
if(exist[x])que[++tque]=x;
if(rs[x])dfs(rs[x]);
return ;
}
int build(int l,int r){
if(l>r)return 0;
int mid=l+r>>1,x=que[mid];
sz[x]=cnt[x]=exist[x]=1,
ls[x]=build(l,mid-1),
rs[x]=build(mid+1,r);
update(x);
return x;
}
void rebuild(int *x){
tque=0,dfs(*x),*x=build(1,tque);
return ;
}
bool isbad(int x){
if(cnt[x]*alpha+5<max(cnt[ls[x]],cnt[rs[x]]))
return 1;
if(sz[x]+5<cnt[x]*sin)return 1;
return 0;
}
void insert(int &x,int d){
if(!x){
x=++tot,
v[x]=d,
sz[x]=cnt[x]=exist[x]=1,
ls[x]=rs[x]=0;
return ;
}
if(d<=v[x])insert(ls[x],d);
else insert(rs[x],d);
update(x);
if(isbad(x))sgt=&x;
return ;
}
void del(int &x,int d){
int num=sz[ls[x]]+exist[x];
if(num==d&&exist[x]){
--sz[x],
exist[x]=0;
return ;
}
if(d<=num)del(ls[x],d);
else del(rs[x],d-num);
update(x);
if(isbad(x))sgt=&x;
return ;
}
void ins(int d){
sgt=NULL,
insert(root,d);
if(sgt)rebuild(sgt);
return ;
}
void erase(int d){
sgt=NULL,
del(root,d);
if(sgt)rebuild(sgt);
return ;
}
int get_low(int x,int d){
if(!x)return 0;
if(d<=v[x]) return get_low(ls[x],d);
else return sz[ls[x]]+exist[x]+get_low(rs[x],d);
}
int findkth(int x,int d){
int num=sz[ls[x]]+exist[x];
if(num==d&&exist[x])return v[x];
if(d<=num)return findkth(ls[x],d);
else return findkth(rs[x],d-num);
}
int main(void){
register int i,x,y;
n=read();
for (i=1;i<=n;++i){
x=read(),y=read();
switch(x){
case 1:ins(y);break;
case 2:erase(get_low(root,y)+1);break;
case 3:printf("%d\n",get_low(root,y)+1);break;
case 4:printf("%d\n",findkth(root,y));break;
case 5:printf("%d\n",findkth(root,get_low(root,y)));break;
default :printf("%d\n",findkth(root,get_low(root,y+1)+1));break;
}
}
return 0;
}