社区讨论

本人萌新,初学OI,替罪羊树写挂了QAQ

P3369【模板】普通平衡树参与者 17已保存回复 23

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
23 条
当前快照
1 份
快照标识符
@mi6xnn17
此快照首次捕获于
2025/11/20 12:30
4 个月前
此快照最后确认于
2025/11/20 16:21
4 个月前
查看原帖
我才初一,真的是萌新QWQ。
CPP
#include<bits/stdc++.h>
const int MAXN=100010;
const int INF=0x7f7f7f7f;
const double alpha=0.75;
typedef double D;
using namespace std;
int n,m,i,j,k,opt,x;
struct sgt{
	int lson,rson,size,val,tot,exist=1;
};
sgt tree[MAXN];
int g[MAXN],temp[MAXN],g_t,root,t_t;
struct io{
	int read(){
		int x=0;char c;
		for(c=getchar();!isdigit(c);c=getchar()) ;
		for(;isdigit(c);c=getchar()) x=x*10+c-48;
		return x;
	}
	void write(int x){
		if(x/10>0) write(x/10);
		putchar(x%10+48);
		return;
	}
}Fio;
#define read Fio.read
#define write Fio.write
namespace SGT{
	bool bad(int x){
		if((D)(max(tree[tree[x].lson].size,tree[tree[x].rson].size))>=tree[x].size*alpha) return 1;
		else return 0;		
	}
	void dfs(int x){
		if(x==0) return;
		dfs(tree[x].lson);
		if(tree[x].exist==1) temp[++t_t]=x;
		else g[++g_t]=x;
		dfs(tree[x].rson);	
	}
	void bulid(int l,int r,int&now){
		int mid=(l+r)/2;
		if(l==r){
			tree[now].lson=0;tree[now].rson;
			tree[now].size=1;tree[now].tot=1;tree[now].exist=1;
			return;
		}
		if(l<r) bulid(l,mid-1,tree[now].lson);
		else tree[now].lson=0;  
		bulid(mid+1,r,tree[now].rson);
		tree[now].size=tree[tree[now].lson].size+tree[tree[now].rson].size+1;
		tree[now].tot=tree[tree[now].lson].tot+tree[tree[now].rson].tot+1;
		return;
	}  
	void rebuild(int&now){
		t_t=0;
		dfs(now);
		if(t_t==0) bulid(1,t_t,now);
		else now=0;
	} 
	void insert(int &now,int val){
		if(now==0){
			now=g[g_t--];
			tree[now].val=val;
			tree[now].lson=0;tree[now].rson=0;
			tree[now].size=1;tree[now].exist=1;tree[now].tot=1;
			return;
		}
		tree[now].size++;tree[now].tot++;
		if(tree[now].val>=val) insert(tree[now].lson,val);
		else insert(tree[now].rson,val);
		if(bad(now)==1) rebuild(now);
	}
	int Qrank(int k){
		int now=root;
		int ans=1;
		while(now>0){
			if(tree[now].val>=k) now=tree[now].lson;
			else{
				ans+=tree[tree[now].lson].size+tree[tree[now].rson].exist;   
				now=tree[now].rson;
			}
		}
		return ans;
	}
	int Frank(int k){
		int now=root;
		while(now>0){
			if(tree[now].exist==1&&tree[tree[now].lson].size+1==k) return tree[now].val;
			if(tree[tree[now].lson].size+1>k) now=tree[now].lson;
			else{
				k-=(tree[tree[now].rson].size+tree[now].exist);
				now=tree[now].rson;		
			}
		}   
		return INF;
	}
	void delRank(int &now,int k){
		if(tree[now].exist==1&&tree[tree[now].lson].size+1==k){
			tree[now].exist=0;tree[now].size--;
			return;			
		}
		tree[now].size--;
		if(tree[tree[now].lson].size+1>=k){
			now=tree[now].lson;
			delRank(now,k);
		}
		else{
			now=tree[now].rson;
			k-=(tree[tree[now].lson].size+tree[now].exist);
			delRank(now,k);
		}
		return; 
	}
	void delNode(int k){
		delRank(root,Frank(k));
		if(tree[root].tot*alpha>=tree[root].size) rebuild(root);
	}
}
int main(){    
	n=read();
	for(int _i=MAXN-1;_i>=1;_i--) g[++g_t]=_i;   
	for(int _i=1;_i<=n;_i++){
		scanf("%d %d",&opt,&x);
		if(opt==1) SGT::insert(root,x);
		else if(opt==2) SGT::delNode(x);
		else if(opt==3) printf("%d\n",SGT::Qrank(x));
		else if(opt==4) printf("%d\n",SGT::Frank(x));  
		else if(opt==5) printf("%d\n",SGT::Frank(SGT::Qrank(x)-1));
		else printf("%d\n",SGT::Frank(SGT::Qrank(x+1)));
	} 
}

回复

23 条回复,欢迎继续交流。

正在加载回复...