替罪羊树44pts,玄关
查看原帖
替罪羊树44pts,玄关
556955
123wbl楼主2024/9/27 22:22
#include<iostream>
#include<cstdio>
#define dd double
using namespace std;
int n,root,tt,ck[2000001],t,len,ans;
double alpha=0.75;
struct edge
{
	int l,r,res,tot;
	int fa,size,trsize,whsize;
	bool tf;
}tree[2000001];
struct sl{int res,tot;}shulie[2000001];
inline int read()
{
	int flag=1,res=0;char ch=getchar();
	while(ch>'9'||ch<'0'){if(ch=='-') flag=-1;ch=getchar();}
	while(ch<='9'&&ch>='0'){res=res*10+ch-48;ch=getchar();}
	return flag*res;
}
inline int kk()
{
	if(t>0) return ck[t--];
	else return ++len;
}
inline int find(int x,int p)
{
	if(x<tree[p].res&&tree[p].l) return find(x,tree[p].l);
	if(x>tree[p].res&&tree[p].r) return find(x,tree[p].r);
	return p;
}
inline void update(int p,int y,int z,int k)
{
	if(!p) return;
	tree[p].trsize+=y;
	tree[p].size+=z;
	tree[p].whsize+=k;
	update(tree[p].fa,y,z,k);
}
inline void build(int x,int p,int fa)
{
	tree[p].l=tree[p].r=0;tree[p].fa=fa,tree[p].tf=false;
	tree[p].res=x;tree[p].tot=tree[p].size=tree[p].trsize=tree[p].whsize=1;
}
inline void dfs_rebuild(int p)
{
	if(p==0) return;
	dfs_rebuild(tree[p].l);
	if(!tree[p].tf) shulie[++tt].res=tree[p].res,shulie[tt].tot=tree[p].tot;
	ck[++t]=p;
	dfs_rebuild(tree[p].r);
}
inline int readd(int l,int r,int fa)
{
	if(l>r) return 0;
	int mid=(l+r)>>1,id=kk();
	tree[id].fa=fa;
	tree[id].tot=shulie[mid].tot;
	tree[id].res=shulie[mid].res;
	tree[id].l=readd(l,mid-1,id);
	tree[id].r=readd(mid+1,r,id);
	tree[id].whsize=shulie[mid].tot+tree[tree[id].l].whsize+tree[tree[id].r].whsize;
	tree[id].size=tree[id].trsize=r-l+1;
	tree[id].tf=false;
	return id;
}
inline void rebuild(int x)
{
	tt=0;
	dfs_rebuild(x);
	if(x==root) root=readd(1,tt,0);
	else
	{
		update(tree[x].fa,0,-(tree[x].size-tree[x].trsize),0);
		if(tree[tree[x].fa].l==x) tree[tree[x].fa].l=readd(1,tt,tree[x].fa);
		else tree[tree[x].fa].r=readd(1,tt,tree[x].fa);
	}
}
inline void find_rebuild(int p,int x)
{
	int l=tree[p].l,r=tree[p].r;
	if((dd)tree[l].size>(dd)tree[p].size*alpha||
	(dd)tree[r].size>(dd)tree[p].size*alpha||
	(dd)tree[p].size-(dd)tree[p].trsize>(dd)tree[p].size*0.4) {rebuild(p);return;}
	if(tree[p].res!=x) find_rebuild(x<tree[p].res? l:r,x);
}
inline void add(int x)
{
	if(!root)
	{
		build(x,root=kk(),0);
		return;
	}
	int p=find(x,root);
	if(x==tree[p].res)
	{
		tree[p].tot++;
		if(tree[p].tf) tree[p].tf=0,update(p,1,0,1);
		else update(p,0,0,1);
	}
	else
	{
		if(tree[p].res>x) build(x,tree[p].l=kk(),p),update(p,1,1,1);
		else build(x,tree[p].r=kk(),p),update(p,1,1,1);
	}
	find_rebuild(root,x);
}
inline void del(int x)
{
	int p=find(x,root);
	tree[p].tot--;
	if(!tree[p].tot) tree[p].tf=true,update(p,-1,0,-1);
	else update(p,0,0,-1);
	find_rebuild(root,x);
}
inline void findxpm(int x)
{
	int now=root;
	int ans=0;
	while(tree[now].res!=x)
	{
		if(x<tree[now].res) now=tree[now].l;
		else ans+=tree[now].tot+tree[tree[now].l].whsize,now=tree[now].r;
	}
	ans+=tree[tree[now].l].whsize;
	printf("%d\n",ans+1);
}
inline void findpmx(int x)
{
	int now=root;
	for(;;)
	{
		if(x<=tree[tree[now].l].whsize) now=tree[now].l;
		else
		{
			x-=tree[tree[now].l].whsize;
			if(x<=tree[now].tot)
			{
				printf("%d\n",tree[now].res);
				return;
			}
			x-=tree[now].tot;
			now=tree[now].r;
		}
	}
}
inline void dfs_rml(int x)
{
	if(tree[x].r) dfs_rml(tree[x].r);
	if(ans) return;
	if(!tree[x].tf)
	{
		printf("%d\n",tree[x].res);
		return;
	}
	if(tree[x].l) dfs_rml(tree[x].l);
}
inline void pre(int now,int x,bool zy)
{
	if(!zy)
	{
		pre(tree[now].fa,x,tree[tree[now].fa].r==now);
		return;
	}
	if(!tree[now].tf&&tree[now].res<x)
	{
		printf("%d\n",tree[now].res);
		return;
	}
	if(tree[now].l)
	{
		ans=false;
		dfs_rml(tree[now].l);
		return;
	}
	pre(tree[now].fa,x,tree[tree[now].fa].r==now);
}
inline void dfs_lmr(int x)
{
	if(tree[x].l) dfs_lmr(tree[x].l);
	if(ans) return;
	if(!tree[x].tf)
	{
		printf("%d\n",tree[x].res);
		return;
	}
	if(tree[x].r) dfs_lmr(tree[x].r);
}
inline void next(int now,int x,bool zy)
{
	if(!zy)
	{
		next(tree[now].fa,x,tree[tree[now].fa].r!=now);
		return;
	}
	if(!tree[now].tf&&tree[now].res>x)
	{
		printf("%d\n",tree[now].res);
		return;
	}
	if(tree[now].r)
	{
		ans=false;
		dfs_lmr(tree[now].r);
		return;
	}
	next(tree[now].fa,x,tree[tree[now].fa].r!=now);
}
int main()
{
	n=read();
	for(int i=1;i<=n;++i)
	{
		int opt,xx;
		opt=read(),xx=read();
		if(opt==1) add(xx);
		if(opt==2) del(xx);
		if(opt==3) findxpm(xx);
		if(opt==4) findpmx(xx);
		if(opt==5) pre(find(xx,root),xx,true);
		if(opt==6) next(find(xx,root),xx,true);
	}
}

T两个点,不知道错哪里了,大佬们帮帮忙

2024/9/27 22:22
加载中...