• QTREE5 Link-Cut Tree


    (Problem Link)

    题目大意

    你被给定一棵n个点的树,点从1到n编号。每个点可能有两种颜色:黑或白。我们定义dist(a,b)为点a至点b路径上的边个数。

    一开始所有的点都是黑色的。

    要求作以下操作:

    0 i 将点i的颜色反转(黑变白,白变黑)

    1 v 询问dist(u,v)的最小值。u点必须为白色(u与v可以相同),显然如果v是白点,查询得到的值一定是0。

    特别地,如果作'1'操作时树上没有白点,输出-1.

    思想分析

    这题的动态点分治做法看我的总结

    这题动态点分治做法还挺简单的,但是LCT做法就复杂一些,不过总体来说还是板子

    我们定义(lmn[x],rmn[x])分别代表在(splay)(x)的子树里深度最浅的点能够到达最近的白点的距离,

    和深度最深的点能够到达最近的白点的距离

    还要开个堆或者(multiset)维护一下子树中的(lmn)最小值.

    这道题询问的是点到最近的白点的距离,所以就不需要维护子树信息了

    不需要拉链,也就不用split,makert,findrt等一大堆操作了

    这个时候LCT还是跑的很快的,比动态点分治快了一倍(qwq)

    代码实现

    /*
    @Date    : 2019-09-10 17:14:38
    @Author  : Adscn (adscn@qq.com)
    @Link    : https://www.cnblogs.com/LLCSBlog
    */
    #include<bits/stdc++.h>
    using namespace std;
    #define IL inline
    #define RG register
    #define gi getint()
    #define gc getchar()
    #define File(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)
    template<typename T>IL bool chkmax(T &x,const T &y){return x<y?x=y,1:0;}
    template<typename T>IL bool chkmin(T &x,const T &y){return x>y?x=y,1:0;}
    IL int getint()
    {
    	RG int xi=0;
    	RG char ch=gc;
    	bool f=0;
    	while(!isdigit(ch))ch=='-'?f=1:f,ch=gc;
    	while(isdigit(ch))xi=xi*10+ch-48,ch=gc;
    	return f?-xi:xi;
    }
    template<typename T>
    IL void pi(T k,char ch=0)
    {
    	if(k<0)k=-k,putchar('-');
    	if(k>=10)pi(k/10,0);
    	putchar(k%10+'0');
    	if(ch)putchar(ch);
    }
    const int N=1e5+7;
    const int inf=1e9;
    int n;
    namespace LCT{
    	int fa[N],ch[N][2],lmn[N],rmn[N],siz[N],col[N];
    	multiset<int>s[N];
    	multiset<int>::iterator it;
    	#define ls(x) (ch[x][0])
    	#define rs(x) (ch[x][1])
    	#define s(x,k) (ch[x][k])
    	inline bool ws(int x,int p){return rs(p)==x;}
    	inline bool nrt(int x){return ls(fa[x])==x||rs(fa[x])==x;}
    	inline int fir(int x){return s[x].empty()?inf:*s[x].begin();}
    	inline void pushup(int x){
    		if(!x)return;
    		siz[x]=siz[ls(x)]+siz[rs(x)]+1;
    		lmn[x]=min(lmn[ls(x)],siz[ls(x)]+min(col[x]?0:inf,min(fir(x),lmn[rs(x)])+1));
    		rmn[x]=min(rmn[rs(x)],siz[rs(x)]+min(col[x]?0:inf,min(fir(x),rmn[ls(x)])+1));
    	}
    	inline void rotate(int x){
    		int p=fa[x],g=fa[p];
    		int t=ws(x,p),w=s(x,!t);
    		if(nrt(p))s(g,ws(p,g))=x;s(x,!t)=p;s(p,t)=w;
    		if(w)fa[w]=p;fa[p]=x;fa[x]=g;
    		pushup(p);
    	}
    	inline void Splay(int x){
    		while(nrt(x))
    		{
    			int p=fa[x],g=fa[p];
    			if(nrt(p))rotate(ws(x,p)^ws(p,g)?x:p);
    			rotate(x);
    		}
    		pushup(x);
    	}
    	inline void access(int x){
    		for(int y=0;x;x=fa[y=x])
    		{
    			Splay(x);
    			s[x].insert(lmn[rs(x)]);
    			if((it=s[x].lower_bound(lmn[y]))!=s[x].end())s[x].erase(it);
    			rs(x)=y,pushup(x);
    		}
    	}
    	inline void modify(int x){
    		access(x),Splay(x);
    		col[x]^=1;
    		pushup(x);
    	}
    	inline int query(int x){
    		access(x);Splay(x);
    		return rmn[x]>n?-1:rmn[x];
    	}
    }
    using namespace LCT;
    struct edge{
    	int v,nxt;
    }e[N<<1|1];
    int head[N],cnt;
    inline void add(int u,int v){e[++cnt]=(edge){v,head[u]},head[u]=cnt;}
    inline void init(){memset(head,cnt=-1,sizeof head);}
    inline void dfs(int x,int p)
    {
    	for(int i=head[x],v;~i;i=e[i].nxt)
    		if((v=e[i].v)^p)
    			fa[v]=x,dfs(v,x);
    }
    int main(void)
    {
    	n=gi,lmn[0]=rmn[0]=inf;
    	init();
    	for(int i=1,u,v;i<n;++i)u=gi,v=gi,add(u,v),add(v,u);
    	dfs(1,0);
    	for(int i=1,m=gi;i<=m;++i)
    	{
    		int opt=gi,x=gi;
    		if(opt^1)modify(x);
    		else pi(query(x),'
    ');
    	}
    	return 0;
    }
    
  • 相关阅读:
    TWaver局部自动布局及嵌套Group处理
    如何在TWaver Flex中定制Tree的tooltip
    为TWaver HTML5的Tree组件增加鼠标滑过效果
    赛瓦软件参加2012中国国际信息通信展览会
    TWaver HTML5 on Microsoft Surface RT
    JTree实现文件树
    kd tree的优化查找算法BBF 【转】
    kd tree代码解析 【转】
    kd tree算法【转】
    基于OpenCV库的Gabor滤波器的实现
  • 原文地址:https://www.cnblogs.com/LLCSBlog/p/11511132.html
Copyright © 2020-2023  润新知