LCT维护子树大小求调
查看原帖
LCT维护子树大小求调
85994
嘉年华楼主2022/2/26 12:44

代码省略了读入

#define maxn 100005
class node
{
	public:
		int c[2],fa;
		bool rev;
		int im_siz,re_siz;
		node(){c[0]=c[1]=fa=im_siz=0,re_siz=0,rev=false;}
};
node d[maxn];
#define fa(x) d[x].fa
#define left_son(x) d[d[x].c[0]]
#define right_son(x) d[d[x].c[1]]

inline bool nroot(int x){return d[fa(x)].c[0]==x||d[fa(x)].c[1]==x;}
inline void push_rev(int x){swap(d[x].c[0],d[x].c[1]),d[x].rev^=1;}
inline void pushdown(int x)
{
	if(d[x].rev)
	{
		if(d[x].c[0]) push_rev(d[x].c[0]);
		if(d[x].c[1]) push_rev(d[x].c[1]);
		d[x].rev=0;
	}
}
inline void push_all(int x)
{
	if(nroot(x)) push_all(fa(x));
	pushdown(x);
}
inline void update(int x)
{
	d[x].re_siz=left_son(x).re_siz+right_son(x).re_siz+d[x].im_siz+1;
}
inline void rotate(int x)
{
	int y=fa(x),z=fa(y),k=(d[y].c[1]==x),w=d[x].c[!k];
	if(nroot(y)) d[z].c[d[z].c[1]==y]=x;
	d[x].c[!k]=y,
	d[y].c[ k]=w;
	if(w) fa(w)=y;
	fa(fa(y)=x)=z;
	update(y);
//	update(x);
	return;
}
inline void splay(int x)
{
	static int y,z;
	push_all(x);
	while(nroot(x))
	{
		y=d[x].fa,z=d[y].fa;
		if(nroot(y)) rotate((d[y].c[0]==x)^(d[z].c[0]==y)?x:y);
		rotate(x);
		update(x);
	}
	
}
inline void access(int x)
{
	for(int y=0;x;x=fa(y=x))
		splay(x),
		d[x].im_siz+=right_son(x).re_siz-d[y].re_siz,
		d[x].c[1]=y,
		update(x);
}
inline void makeRoot(int x)
{
	access(x),
	splay(x),
	push_rev(x);
}
inline int findRoot(int x)
{
	access(x),splay(x);
	while(d[x].c[0]) pushdown(x),x=d[x].c[0];
	splay(x);
	return x;
}
inline void link(int x,int y)
{
	makeRoot(x);
	if(findRoot(y)^x)
		fa(x)=y,
		d[y].im_siz+=d[x].re_siz,
		update(y);
}
inline void cut(int x,int y)
{
	makeRoot(x);
	if(findRoot(y)==x&&!d[y].c[0]&&fa(y)==x)
		d[x].c[1]=fa(y)=0,
		update(x);
}
inline void split(int x,int y)
{
	makeRoot(x),
	access(y),
	splay(y);
}
int n,m;
ll ans;

signed main()
{
	read_(n),read_(m);
	char op;
	for(int x,y,i=1;i<=m;++i)
	{
		for(op=getchar();op<'A'||op>'Z';op=getchar());
		read_(x),read_(y);
		if(op=='A') link(x,y);
		else
			cut(x,y),
			makeRoot(x),
			makeRoot(y),
			cout<<(ll)d[x].re_siz*(ll)d[y].re_siz<<'\n',
			link(x,y);
	}
    return 0;
}
2022/2/26 12:44
加载中...