明明与题解一样,为啥效率差了好多,希望大佬能来看看。 本蒟蒻的代码:
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 2e5+5;
const double alph = 0.7;
struct node{
int ch[2],val,size,real_size,fa;
bool real;
}tree[MAXN];
int tot,cnt,n,root,tmp[MAXN],e;
void update(int now){
tree[now].size = tree[tree[now].ch[0]].size + tree[tree[now].ch[1]].size + 1;
tree[now].real_size = tree[tree[now].ch[0]].real_size + tree[tree[now].ch[1]].real_size + tree[now].real;
}
bool isbad(int now){
if(1.0 * alph * tree[now].size < tree[tree[now].ch[0]].size || 1.0 * alph * tree[now].size < tree[tree[now].ch[1]].size)
return true;
return false;
}
void dfs(int now){
if(!now) return;
dfs(tree[now].ch[0]);
if(tree[now].real) tmp[++cnt] = now;
dfs(tree[now].ch[1]);
}
void build(int l,int r,int &now,int fa){ //注意 now 是引用
// if(l > r){
// now = 0;
// return;
// }
int mid = (l+r)>>1;
now = tmp[mid];
tree[now].fa = fa;
if(l == r){
tree[now].size = tree[now].real_size = 1;
tree[now].ch[0] = tree[now].ch[1] = 0;
return;
}
if(l < mid) build(l,mid-1,tree[now].ch[0],now);
else tree[now].ch[0] = 0;
build(mid+1,r,tree[now].ch[1],now);
update(now);
}
void rebuild(int &now){
cnt = 0;
dfs(now);
if(cnt)
build(1,cnt,now,0);
else
now = 0;
}
void Insert(int &now,int x){
if(!now){
now = ++tot;
tree[now].size = tree[now].real_size = 1;
tree[now].ch[0] = tree[now].ch[1] = 0;
tree[now].real = true;
tree[now].val = x;
return;
}
tree[now].size++;tree[now].real_size++;
if(x <= tree[now].val) Insert(tree[now].ch[0],x);
else Insert(tree[now].ch[1],x);
if(isbad(now)){
e = now;
}
}
int rk(int x){
int ans = 1,now = root;
while(now){
if(x <= tree[now].val){
now = tree[now].ch[0];
}
else{
ans += tree[tree[now].ch[0]].real_size + tree[now].real; //可能 now 节点不存在了
now = tree[now].ch[1];
}
}
return ans;
}
int K_th(int x){
int now = root;
// if(tree[now].real_size < x) return -1;
while(now){
if(tree[now].real && x == tree[tree[now].ch[0]].real_size + 1){
return tree[now].val;
}
else if(x <= tree[tree[now].ch[0]].real_size){
now = tree[now].ch[0];
}
else{
x -= tree[tree[now].ch[0]].real_size + tree[now].real;
now = tree[now].ch[1];
}
}
}
void Delet(int now,int x){
if(tree[now].real && tree[tree[now].ch[0]].real_size + 1 == x){
tree[now].real = false;
tree[now].real_size--;
return;
}
tree[now].real_size--;
if(x > tree[tree[now].ch[0]].real_size + tree[now].real)
Delet(tree[now].ch[1],x - (tree[tree[now].ch[0]].real_size + tree[now].real));
else{
Delet(tree[now].ch[0],x);
}
}
int main(){
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
// cin>>n;
scanf("%d",&n);
for(int i=1; i<=n; i++){
int opt,x;
// cin>>opt>>x;
scanf("%d%d",&opt,&x);
if(opt == 1){
Insert(root,x);
if(e){
if(e == root) //我们的 rebuild 是引用,所以要这样写,不能直接 rebuild(e)
rebuild(root);
else
rebuild(tree[root].ch[tree[root].ch[1] == e]);
e = 0;
}
}
else if(opt == 2){
Delet(root,rk(x));
if(1.0 * tree[root].size * alph > tree[root].real_size){
rebuild(root);
}
}
else if(opt == 3){
printf("%d\n",rk(x));
}
else if(opt == 4){
printf("%d\n",K_th(x));
}
else if(opt == 5){
printf("%d\n",K_th(rk(x)-1));
}
else if(opt == 6){
printf("%d\n",K_th(rk(x+1)));
}
}
return 0;
}