• SPOJ 2939 QTREE5 LCT


    维护信息的方式十分巧妙~

    维护每一棵 splay 中深度最浅,深度最深的点距离最近的白点.   

    这样非常方便维护,进行区间合并,进行子树维护 

    很多时候在维护东西的时候最大/最小/深度最小/深度最大会相对容易维护,所以如果用树剖/LCT维护信息时发现很难维护的话可以采用这种套路.

    因为动态树是可以维护子树信息的,也可以 ,所以如果维护深度最深的信息的话只需 就可以做到.

    code:

    #include <bits/stdc++.h>  
    #define N 100006 
    #define inf 1000000 
    #define setIO(s) freopen(s".in","r",stdin) 
    using namespace std;     
    int n,edges; 
    int hd[N],to[N<<1],nex[N<<1],col[N];    
    void add(int u,int v) 
    {
    	nex[++edges]=hd[u],hd[u]=edges,to[edges]=v; 
    } 
    struct Link_Cut_Tree
    { 
    	#define lson p[x].ch[0] 
    	#define rson p[x].ch[1]        
    	struct Node 
    	{
    		int ch[2],f,size,lmn,rmn;    
    		multiset<int>s;    
    		int get() { return s.empty()?inf:*s.begin(); }
    	}p[N];        
    	int get(int x) { return p[p[x].f].ch[1]==x; } 
    	int isrt(int x) { return !(p[p[x].f].ch[0]==x||p[p[x].f].ch[1]==x); } 
    	void pushup(int x) 
    	{
    		p[x].size=p[lson].size+p[rson].size+1;   
    		p[x].lmn=min(p[lson].lmn, p[lson].size+min(col[x]?0:inf, min(p[x].get(), p[rson].lmn+1)));
    		p[x].rmn=min(p[rson].rmn, p[rson].size+min(col[x]?0:inf, min(p[x].get(), p[lson].rmn+1)));         	
    	}
    	void rotate(int x) 
    	{
    		int old=p[x].f,fold=p[old].f,which=get(x);  
    		if(!isrt(old)) p[fold].ch[p[fold].ch[1]==old]=x;    
    		p[old].ch[which]=p[x].ch[which^1],p[p[old].ch[which]].f=old; 
    		p[x].ch[which^1]=old,p[old].f=x,p[x].f=fold; 
    		pushup(old),pushup(x); 
    	}  
    	void splay(int x) 
    	{
    		int u=x,v=0,fa;
    		for(;!isrt(u);u=p[u].f);   
    		for(u=p[u].f;(fa=p[x].f)!=u;rotate(x)) 
    		    if(p[fa].f!=u) 
    			    rotate(get(fa)==get(x)?fa:x); 
    	}
    	void Access(int x) 
    	{
    		for(int y=0;x;y=x,x=p[x].f) 
    		{
    		    splay(x); 
    			if(rson) 
    			{
    				p[x].s.insert(p[rson].lmn+1);      
    			}
    			if(y) 
    			{
    				p[x].s.erase(p[x].s.find(p[y].lmn+1));    
    			}
    			rson=y; 
    			pushup(x); 
    		}
    	}    
    	#undef lson 
    	#undef rson 
    }lct;  
    void dfs(int u,int ff) 
    {
    	lct.p[u].f=ff;     
    	for(int i=hd[u];i;i=nex[i]) 
    	{
    		int v=to[i]; 
    		if(v==ff) continue;               
    		dfs(v,u);        
    		lct.p[u].s.insert(inf+1); 
    	}   
    	lct.pushup(u); 
    }
    int main() 
    { 
    	// setIO("input"); 
    	int i,j; 
    	scanf("%d",&n); 
    	for(i=1;i<n;++i) 
    	{
    		int u,v; 
    		scanf("%d%d",&u,&v); 
    		add(u,v); 
    		add(v,u); 
    	} 
    	lct.p[0].lmn=lct.p[0].rmn=inf;   
    	dfs(1,0);               
    	int m; 
    	scanf("%d",&m); 
    	for(i=1;i<=m;++i) 
    	{
    		int op,u; 
    		scanf("%d%d",&op,&u);    
    		if(op==0) 
    		{
    			lct.Access(u); 
    			lct.splay(u);    
    			col[u]^=1;    
    			lct.pushup(u);     
    		}
    		else 
    		{
    			lct.Access(u);  
    			lct.splay(u);    
    			printf("%d
    ",lct.p[u].rmn>n?-1:lct.p[u].rmn);    
    		}  
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    【Zookeeper】分布式服务框架 Zookeeper -- 管理分布式环境中的数据
    【Consul】 分布式环境中的服务注册和发现利器
    springboot集成springsession利用redis来实现session共享
    OpenResty初涉
    java面试之闭包(closure)
    集合框架学习之Guava Collection
    本地缓存
    VLFeat在matlab和vs中安装
    HashCode与Equals回顾
    集合工具类CollectionUtils、ListUtils、SetUtils、MapUtils的使用
  • 原文地址:https://www.cnblogs.com/guangheli/p/11672369.html
Copyright © 2020-2023  润新知