求调平衡树
  • 板块灌水区
  • 楼主abigben
  • 当前回复2
  • 已保存回复2
  • 发布时间2022/1/26 16:57
  • 上次更新2023/10/28 10:52:02
查看原帖
求调平衡树
288208
abigben楼主2022/1/26 16:57
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
inline int read(){
	int k=0,f=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9')k=k*10+c-'0',c=getchar();
	return k*f;
}
int n;
struct Tree{
	int now,sz[N],cnt[N],ch[N][2],val[N],fa[N],root;
	inline void cl(int x){sz[x]=cnt[x]=ch[x][0]=ch[x][1]=fa[x]=val[x]=0;}
	inline void update(int x){
		sz[x]=cnt[x];
		if(ch[x][0])sz[x]+=sz[ch[x][0]];
		if(ch[x][1])sz[x]+=sz[ch[x][1]];
	}
	inline int get(int x){
		return ch[fa[x]][1]==x;
	}
	inline void set(int x){
		now++;cl(now);cnt[now]=sz[now]=1;val[now]=x;
	}
	/*inline void splay(int x){
		int F=fa[x];
		int k=get(x),kx=get(F),G=ch[x][k^1];
		ch[x][k^1]=F;ch[F][k]=G;
		if(fa[F])ch[fa[F]][kx]=x;
		fa[x]=fa[F];fa[G]=F;fa[F]=x;
		update(F);update(x);
	}*/
	inline void splay(int x){
     int old=fa[x],oldf=fa[old],which=get(x);
     ch[old][which]=ch[x][which^1];fa[ch[old][which]]=old;
     fa[old]=x;ch[x][which^1]=old;
     fa[x]=oldf;
     if (oldf)
          ch[oldf][ch[oldf][1]==old]=x;
     update(old);update(x);
	} 
	/*inline void xz(int x){
		while(fa[x]){
			int F=fa[x];
			if(!fa[F])splay(x);
			else{
				splay((get(F)==get(x))?F:x);
				splay(x);
			}
		}
		root=x;fa[x]=0;
	}*/
	inline void xz(int x){
     for (int f;(f=fa[x]);splay(x))
          if (fa[f])
               splay((get(x)==get(f)?f:x));
     root=x;
	}
	inline void insert(int x){
		if(!root){set(x);root=now;return;}
		int k=root;
		while(1){
			if(val[k]==x){
				cnt[k]++;xz(k);
				return;
			}
			int kp=ch[k][x>val[k]];
			if(!kp){
				set(x);fa[now]=k;ch[k][x>val[k]]=now;
				xz(now);return;
			}
			k=kp;
		}
	}
	inline int find(int x){
		int k=root,s=0;
		while(1){
			if(x<val[k])k=ch[k][0];
			else{
				if(val[k]==x){return s+1;}
				s+=ch[k][0]+cnt[k];
				k=ch[k][1];
			}
		}
		return 0;
	}
	inline int FF(int x){
		int k=root,s=0;
		while(1){
		//	cout<<"FAQ "<<k<<endl;
			if(x<val[k])k=ch[k][0];
			else{
				if(val[k]==x){return k;}
				s+=ch[k][0]+cnt[k];
				k=ch[k][1];
			}
		}
		return 0;
	}
	inline int pre(){
		int k=ch[root][0];
		while(k){
			if(ch[k][1])k=ch[k][1];
			else return k;
		}
		return k;
	}
	inline int nxt(){
		int k=ch[root][1];
		while(k){
			if(ch[k][0])k=ch[k][0];
			else return k;
		}
		return k;
	}
	inline int pm(int x){
		int s=0,k=root;
		while(1){
		//	cout<<"FAQ "<<k<<" "<<val[k]<<" "<<s<<endl;
			if(!k)return 0;
			if(s+1==x)return val[k];
			if(sz[ch[k][0]]+s>=x)k=ch[k][0];
			else s+=sz[ch[k][0]],k=ch[k][1];
		}
		return 0;
	}
	inline void del(int x){
		int k=FF(x);xz(k);
		if(cnt[k]>1){cnt[k]--;update(k);return;}
		if(!ch[k][0]&&!ch[k][1]){
			root=0;cl(k);
			return;
		}
		if(!ch[k][0]||!ch[k][1]){
			int kp=ch[k][0]|ch[k][1];
			root=kp;fa[kp]=0;
			return;
		}
		int p=pre();
		xz(p);
		ch[p][1]=ch[k][1];fa[ch[k][1]]=p;
		update(p);
	}
}T;
int main(){
	n=read();
	while(n--){
		int op=read(),x=read();
		if(op==1)T.insert(x);
		if(op==2)T.del(x);
		if(op==3)printf("%d\n",T.find(x));
		if(op==4)printf("%d\n",T.pm(x));
		if(op==5){
			T.insert(x);printf("%d\n",T.val[T.pre()]);
			T.del(x);
		}
		if(op==6){
			T.insert(x);printf("%d\n",T.val[T.nxt()]);
			T.del(x);
		}
	}
	return 0;
} 
2022/1/26 16:57
加载中...