zoukankan      html  css  js  c++  java
  • 【刷题】COGS 2701 动态树

    ★★★☆

    输入文件:dynamic_tree.in

    输出文件:dynamic_tree.out

    简单对比

    时间限制:1 s 内存限制:256 MB

    【题目描述】

    开始时有n个点形成的森林,共m个操作。tp=1时,接下来一个参数u,表示将u所在的树树根变为u。tp=2时,接下来一个参数u,询问以u为根的子树的大小。tp=3时,接下来两个参数u,v,添加一条边(u,v),并将u所在树的根作为两棵树合并后的根。

    【输入格式】

    第一行两个整数n,m。

    接下来m行,每行开头是一个整数tp。tp=1或tp=2时,接下来一个整数u。tp=3时,接下来两个整数(u,v)。

    【输出格式】

    对于每个询问,你需要输出以u为根的子树大小。

    【样例输入】

    5 10
    3 2 3
    3 4 5
    3 2 4
    2 1
    2 5
    3 1 2
    2 4
    1 3
    2 1
    2 4
    

    【样例输出】

    1
    1
    2
    1
    2
    

    【数据范围】

    n<=200000,m<=400000

    【题解】

    裸的LCT维护子树信息

    操作一直接makeroot

    操作二,access后输出点的虚子树信息,把虚子树维护点数+1输出。为什么是虚子树?可以自己画一张图,发现因为是access,所以点把它所有原树中儿子的边全部断掉了,变成虚边,而重边要么没有,要么只有左儿子(满足深度随中序遍历递增),但这左儿子显然深度是小于当前点的,也就是说左儿子是当前点在原树中的父亲(祖先),反正不是儿子,所以不能加实子树信息

    操作三,存下之前的rt,然后连边,再makeroot

    #include<bits/stdc++.h>
    #define ll long long
    #define db double
    #define ld long double
    const int MAXN=200000+10;
    int n,m;
    #define lc(x) ch[(x)][0]
    #define rc(x) ch[(x)][1]
    struct LCT{
    	int ch[MAXN][2],fa[MAXN],rev[MAXN],size[MAXN],Isize[MAXN],stack[MAXN],cnt;
    	inline bool nroot(int x)
    	{
    		return lc(fa[x])==x||rc(fa[x])==x;
    	}
    	inline void reverse(int x)
    	{
    		std::swap(lc(x),rc(x));
    		rev[x]^=1;
    	}
    	inline void pushup(int x)
    	{
    		size[x]=size[lc(x)]+size[rc(x)]+Isize[x]+1;
    	}
    	inline void pushdown(int x)
    	{
    		if(rev[x])
    		{
    			if(lc(x))reverse(lc(x));
    			if(rc(x))reverse(rc(x));
    			rev[x]=0;
    		}
    	}
    	inline void rotate(int x)
    	{
    		int f=fa[x],p=fa[f],c=(rc(f)==x);
    		if(nroot(f))ch[p][rc(p)==f]=x;
    		fa[ch[f][c]=ch[x][c^1]]=f;
    		fa[ch[x][c^1]=f]=x;
    		fa[x]=p;
    		pushup(f);
    		pushup(x);
    	}
    	inline void splay(int x)
    	{
    		cnt=0;
    		stack[++cnt]=x;
    		for(register int i=x;nroot(i);i=fa[i])stack[++cnt]=fa[i];
    		while(cnt)pushdown(stack[cnt--]);
    		for(register int y=fa[x];nroot(x);rotate(x),y=fa[x])
    			if(nroot(y))rotate((lc(y)==x)==(lc(fa[y])==y)?y:x);
    		pushup(x);
    	}
    	inline void access(int x)
    	{
    		for(register int y=0;x;x=fa[y=x])
    		{
    			splay(x);
    			Isize[x]+=size[rc(x)];
    			rc(x)=y;
    			Isize[x]-=size[rc(x)];
    			pushup(x);
    		}
    	}
    	inline int findroot(int x)
    	{
    		access(x);splay(x);
    		while(lc(x))pushdown(x),x=lc(x);
    		splay(x);
    		return x;
    	}
    	inline void makeroot(int x)
    	{
    		access(x);splay(x);reverse(x);
    	}
    	inline void link(int x,int y)
    	{
    		makeroot(x);access(y);splay(y);
    		fa[x]=y;
    		Isize[y]+=size[x];
    		pushup(y);
    	}
    };
    LCT T;
    #undef lc
    #undef rc
    template<typename T> inline void read(T &x)
    {
    	T data=0,w=1;
    	char ch=0;
    	while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
    	if(ch=='-')w=-1,ch=getchar();
    	while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();
    	x=data*w;
    }
    template<typename T> inline void write(T x,char c='')
    {
    	if(x<0)putchar('-'),x=-x;
    	if(x>9)write(x/10);
    	putchar(x%10+'0');
    	if(c!='')putchar(c);
    }
    template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
    template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
    template<typename T> inline T min(T x,T y){return x<y?x:y;}
    template<typename T> inline T max(T x,T y){return x>y?x:y;}
    int main()
    {
    	freopen("dynamic_tree.in","r",stdin);
    	freopen("dynamic_tree.out","w",stdout);
    	read(n);read(m);
    	while(m--)
    	{
    		int opt;
    		read(opt);
    		if(opt==1)
    		{
    			int u;
    			read(u);
    			T.makeroot(u);
    		}
    		if(opt==2)
    		{
    			int u;
    			read(u);
    			T.access(u);
    			write(T.Isize[u]+1,'
    ');
    		}
    		if(opt==3)
    		{
    			int u,v,rt;
    			read(u);read(v);
    			rt=T.findroot(u);
    			T.link(u,v);T.makeroot(rt);
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    在IIS7中应用Application Request Routing配置反向代理
    sqlite数据类型(时间 日期 ) timestamp 使用
    Windows环境下搭建Redis集群(Redis-x64-3.2.100)
    Vertx上传 官网Demo Java版
    Vert.x HTTP 服务器与客户端
    vertx-mysql-client/java/
    vertx-jersey
    Vertx和Jersey集成使用
    jersey常用注解解释 JAX-RS常用注解:
    Statement及PreparedStatement执行多个sql
  • 原文地址:https://www.cnblogs.com/hongyj/p/8722411.html
Copyright © 2011-2022 走看看