zoukankan      html  css  js  c++  java
  • [HEOI2016/TJOI2016]树

    就上树剖。
    维护区间最右端的点。
    主要是顺手复习一下树剖。
    30min手速很不错。

    #include<iostream>
    #include<cstdio>
    #define ll long long
    #define N 100005
    
    ll n;
    
    ll head[N];
    struct P{
    	int to,next;
    }e[N << 1];
    
    ll cnt;
    
    inline void add(int x,int y){
    	e[++cnt].to = y;
    	e[cnt].next = head[x];
    	head[x] = cnt;
    }
    
    ll q;
    
    ll siz[N],dfn[N],idfn[N],dep[N],son[N],top[N],fa[N];
    
    inline void dfs1(int x,int f){
    	siz[x] = 1;
    	dep[x] = dep[f] + 1;
    	fa[x] = f;
    	for(int i = head[x];i;i = e[i].next){
    		int v = e[i].to;
    		if(v == f)continue;
    		dfs1(v,x);
    		if(siz[v] > siz[son[x]])
    		son[x] = v;
    		siz[x] += siz[v];
    	}
    }
    
    ll dfncnt;
    
    inline void dfs2(int u,int t){
    	dfn[u] = ++dfncnt;
    	idfn[dfncnt] = u;
    	top[u] = t;
    	if(son[u])dfs2(son[u],t);
    	for(int i = head[u];i;i = e[i].next){
    		int v = e[i].to;
    		if(v == fa[u] || v == son[u])continue;
    		dfs2(v,v);
    	}
    } 
    
    struct Tree{int right;}T[N << 4];
    
    #define ls(x) (x << 1)
    #define rs(x) (x << 1 | 1)
    #define root 1,1,n
    #define r(x) T[x].right
    #define mid ((l + r) >> 1)
    
    inline void up(int x){
    	if(r(rs(x)))
    	r(x) = r(rs(x));
    	else
    	r(x) = r(ls(x));
    }
    
    inline void Add(int x,int l,int r,int to){
    	if(l == r){
    		r(x) = idfn[l];
    		return;
    	}
    	if(to <= mid)
    	Add(ls(x),l,mid,to);
    	else
    	Add(rs(x),mid + 1,r,to);
    	up(x);
    }
    
    inline ll find(int x,int l,int r,int tl,int tr){
    	if(tl <= l && r <= tr){
    		return r(x);
    	}
    	ll p = 0;
    	if(tr > mid)
    	p = find(rs(x),mid + 1,r,tl,tr);
    	if(!p && tl <= mid)
    	p = find(ls(x),l,mid,tl,tr);
    	return p; 
    }
    
    int main(){
    	scanf("%lld%lld",&n,&q);
    	for(int i = 1;i < n;++i){
    		ll x,y;
    		scanf("%lld%lld",&x,&y);
    		add(x,y);
    		add(y,x);
    	}
    	dfs1(1,0);
    	dfs2(1,1);
    	Add(root,1);
    	while(q -- ){
    		char a = getchar();
    		while(a != 'C' && a != 'Q')
    		a = getchar();
    		if(a == 'C'){
    			ll x;
    			scanf("%lld",&x);
    			Add(root,dfn[x]);
    		}
    		if(a == 'Q'){
    			ll ans = 0;
    			ll x;
    			scanf("%lld",&x);
    			while(x){
    				ans = find(root,dfn[top[x]],dfn[x]);
    				if(ans)
    				break;
    				x = fa[top[x]];
    			}
    			std::cout<<ans<<std::endl;
    		}
    		a = '.';
    	}
    }
    
  • 相关阅读:
    【算法总结】多项式相关
    【算法总结】积性函数相关
    【算法总结】概率与期望相关
    【算法总结】博弈论相关
    【算法总结】线性代数相关
    【算法总结】根号算法相关
    【算法总结】计算几何相关
    【算法总结】组合数学相关
    【算法总结】字符串相关
    【算法总结】数论相关
  • 原文地址:https://www.cnblogs.com/dixiao/p/15206312.html
Copyright © 2011-2022 走看看