zoukankan      html  css  js  c++  java
  • 遥远的国度

    应该是个已经做烂了的经典套路题

    虽然题目要求换根
    但是实际上并不需要

    只要分情况讨论即可

    如果查询的(x=root)直接查询整颗树

    如果(x)(root)的祖先相当于把整颗树拎起来
    查询的实际上是整颗树除了(root)所在的以(x)的儿子为根节点的子树的部分

    否则查询的还是(x)的子树

    具体可以想象一下(root)(x)的情况,想象一下把从(root)整颗树拎起来会变成什么样

    然后就是树剖板子了

    #include<bits/stdc++.h>
    
    using namespace std;
    
    #define gc c=getchar()
    #define r(x) read(x)
    #define ls (rt<<1)
    #define rs (rt<<1|1)
    
    template<typename T>
    inline void read(T&x){
        x=0;T k=1;char gc;
        while(!isdigit(c)){if(c=='-')k=-1;gc;}
        while(isdigit(c)){x=x*10+c-'0';gc;}x*=k;
    }
    
    const int N=100005;
    
    vector<int> G[N];
    
    int ac[N][20],dep[N],siz[N],son[N];
    void dfs1(int x,int f){
    	ac[x][0]=f;
    	dep[x]=dep[f]+1;
    	siz[x]=1;
    	for(int i=1;(ac[x][i]=ac[ac[x][i-1]][i-1]);++i);
    	for(int i=0;i<G[x].size();++i){
    		int v=G[x][i];
    		if(v==f)continue;
    		dfs1(v,x);
    		siz[x]+=siz[v];
    		if(siz[v]>siz[son[x]])son[x]=v;
    	}
    }
    
    int top[N],dfn[N],ptn[N],dfs_clock;
    void dfs2(int x,int t){
        top[x]=t;
        dfn[x]=++dfs_clock;
        ptn[dfs_clock]=x;
        if(son[x])dfs2(son[x],t);
        for(int i=0;i<G[x].size();++i){
            int v=G[x][i];
            if((v==ac[x][0])||(v==son[x]))continue;
    		dfs2(v,v);
        }
    }
    
    inline int find(int x,int t){
    	for(int i=17;~i;--i){
    		if(dep[x]-dep[t]>(1<<i))x=ac[x][i];
    	}
    	assert(ac[x][0]==t);
    	return x;
    }
    
    struct Seg{
    	int min,tag;
    }tr[N<<2];
    
    int a[N];
    
    inline void update(int rt){
    	tr[rt].min=min(tr[ls].min,tr[rs].min);
    }
    
    inline void pushdown(int rt){
    	if(tr[rt].tag){
    		tr[ls].min=tr[rs].min=tr[ls].tag=tr[rs].tag=tr[rt].tag;
    		tr[rt].tag=0;
    	}
    }
    
    void build(int rt,int l,int r){
    	if(l==r){
    		tr[rt].min=a[ptn[l]];
    		return ;
    	}
    	int mid=(l+r)>>1;
    	build(ls,l,mid);
    	build(rs,mid+1,r);
    	update(rt);
    }
    
    void modify(int rt,int l,int r,int x,int y,int v){
    	if(x<=l&&r<=y){
    		tr[rt].min=tr[rt].tag=v;
    		return ;
    	}
    	pushdown(rt);
    	int mid=(l+r)>>1;
    	if(x<=mid)modify(ls,l,mid,x,y,v);
    	if(y>mid)modify(rs,mid+1,r,x,y,v);
    	update(rt);
    }
    
    int query(int rt,int l,int r,int x,int y){
    	if(x>y)return 1e9;
    	if(x<=l&&r<=y)return tr[rt].min;
    	pushdown(rt);
    	int mid=(l+r)>>1;
    	if(y<=mid)return query(ls,l,mid,x,y);
    	else if(x>mid)return query(rs,mid+1,r,x,y);
    	else return min(query(ls,l,mid,x,y),query(rs,mid+1,r,x,y));
    }
    
    int root,n,m;
    
    inline void modify(int u,int v,int w){
        while(top[u]!=top[v]){
            if(dep[top[u]]<dep[top[v]])swap(u,v);
            modify(1,1,n,dfn[top[u]],dfn[u],w);
            u=ac[top[u]][0];
        }
        if(dep[u]>dep[v])swap(u,v);
        modify(1,1,n,dfn[u],dfn[v],w);
        return ;
    }
    
    inline int query(int x){
    	if(x==root)return query(1,1,n,1,n);
    	if(dfn[x]<dfn[root]&&dfn[root]<dfn[x]+siz[x]){
    		int t=find(root,x);
    		return min(query(1,1,n,1,dfn[t]-1),query(1,1,n,dfn[t]+siz[t],n));
    	}
    	return query(1,1,n,dfn[x],dfn[x]+siz[x]-1);
    }
    
    int main(){
    	r(n),r(m);
    	for(int i=1,u,v;i<n;++i){
    		r(u),r(v);
    		G[u].push_back(v);
    		G[v].push_back(u);
    	}
    	for(int i=1;i<=n;++i)r(a[i]);
    	r(root);
    	dfs1(1,0);
    	dfs2(1,1);
    	build(1,1,n);
    	for(int i=1,opt,l,r,x;i<=m;++i){
    		r(opt);
    		if(opt==1)r(root);
    		else if(opt==2){
    			r(l),r(r),r(x);
    			modify(l,r,x);
    		}
    		else {
    			r(x);
    			printf("%d
    ",query(x));
    		}
    	}
    }
    
    
  • 相关阅读:
    【bzoj5110】Yazid的新生舞会
    【2018.12.17】NOI模拟赛4
    【CTSC2010】产品销售(bzoj1920)
    自创模拟赛集合
    【基础操作】FFT / DWT / NTT / FWT 详解
    【2018.12.10】NOI模拟赛3
    【CTSC2009】移民站选址
    【THUSC2016】成绩单(bzoj4897)
    【基础操作】凸包
    【2018.11.26】玄机 / 画心 / 求索
  • 原文地址:https://www.cnblogs.com/yicongli/p/9822700.html
Copyright © 2011-2022 走看看