替罪羊树 TLE 求助
查看原帖
替罪羊树 TLE 求助
544860
linyihdfj楼主2022/3/16 19:57

明明与题解一样,为啥效率差了好多,希望大佬能来看看。 本蒟蒻的代码:

#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;
} 
2022/3/16 19:57
加载中...