替罪羊树 RE 求助,悬三小号关注
查看原帖
替罪羊树 RE 求助,悬三小号关注
571147
zhlzt楼主2023/7/23 15:25
#include<bits/stdc++.h>
using namespace std;
const int N=100000;
const double alpha=0.75;
struct scapegoat{
	int val,ls,rs,del,size,cnt;
}tree[N+10]; int cnt=0,root=0,top=0;
int order[N+10],treestack[N+10];
void inorder(int p){
	if(tree[p].ls!=0) inorder(tree[p].ls);
	if(tree[p].del==1) order[++cnt]=p;
	else treestack[++top]=p;
	if(tree[p].rs!=0) inorder(tree[p].rs);
}
void initnode(int p){
	tree[p].ls=0; tree[p].rs=0;
	tree[p].del=tree[p].size=tree[p].cnt=1;
}
void pushup(int p){ 
	int pl=tree[p].ls,pr=tree[p].rs;
	tree[p].size=tree[pl].size+tree[pr].size+1;
	tree[p].cnt=tree[pl].cnt+tree[pr].cnt+1;
}
void build(int pl,int pr,int &p){
	int mid=pl+pr>>1; p=order[mid];
	if(pl==pr){initnode(p);return;}
	if(pl<mid) build(pl,mid-1,tree[p].ls);
	if(pl==mid) tree[p].ls=0;
	build(mid+1,pr,tree[p].rs); pushup(p);
}
void rebuild(int &p){ cnt=0; inorder(p);
	if(p!=0) build(1,cnt,p); else p=0;
} 
bool notbalance(int p){
	int pl=tree[p].ls,pr=tree[p].rs;
	double p1=tree[p].size*alpha;
	double p2=max(tree[pl].size,tree[pr].size);
	return p2>p1; // 判断子替罪羊树是否平衡 
}
void updateinsert(int &p,int q){
	if(p==0){  p=treestack[top--]; 
		tree[p].val=q; initnode(p); return;
	} tree[p].size++; tree[p].cnt++;
	if(tree[p].val>=q) updateinsert(tree[p].ls,q);
	else updateinsert(tree[p].rs,q);
	if(notbalance(p)) rebuild(p);
}
int queryrank(int p,int q){ 
	if(p==0) return 0; // 如果为空 
	int pl=tree[p].ls,pr=tree[p].rs;
	if(q<=tree[p].val) return queryrank(pl,q);
	return queryrank(pr,q)+tree[pl].size+tree[p].del;
}
int querykth(int p,int q){
	int pl=tree[p].ls,pr=tree[p].rs;
	if(tree[p].del&&tree[pl].size+1==q) return tree[p].val;
	if(tree[pl].size>=q) return querykth(pl,q);
	else querykth(pr,q-tree[pl].size-tree[p].del);
}
void deletenode(int &p,int q){ 
	int pl=tree[p].ls,pr=tree[p].rs; tree[p].size--;
	if(tree[p].del&&tree[pl].size+1==q){tree[p].del=0;return;}
	if(tree[pl].size>=q) deletenode(pl,q);
	else deletenode(pr,q-tree[pl].size-tree[p].del);
}
void updatedelete(int p){
	deletenode(root,queryrank(root,p)+1);
	if(tree[p].cnt*alpha>tree[p].size) rebuild(p);
}
int main(){
	for(int i=N;i>=1;i--) treestack[++top]=i;
	int q;scanf("%d",&q); while(q--){ 
		int opt,p;scanf("%d%d",&opt,&p);
		if(opt==1) updateinsert(root,p);
		if(opt==2) updatedelete(p);
		if(opt==3) printf("%d\n",queryrank(root,p)+1);
		if(opt==4) printf("%d\n",querykth(root,p));
		if(opt==5) printf("%d\n",querykth(root,queryrank(root,p)));
		if(opt==6) printf("%d\n",querykth(root,queryrank(root,p+1)+1));
	}
	return 0;
}
2023/7/23 15:25
加载中...