zoukankan      html  css  js  c++  java
  • CF741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths —dsu on tree

    运用点分治的思想,dsu的处理方式,每个点作为根只考虑跨过自己的最大路径长度
    对于其他路径,直接由子树继承即可

    开桶max_dep[i]记录子树中到根节点1路径上信息异或和为i的最大节点深度。

    考虑跨过自己的最大路径长度分两种,
    第一种是端点在不同子树,对于每个子树,先更新根的ans,再更新max_dep
    第二种是根节点为一端点,另一端点在子树中的,统计完第一种统计这个即可

    Code
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #define rint register int
    using namespace std;
    const int maxn=5e5+5;
    const int maxs=1<<22;
    const int INF=0x3f3f3f3f;
    int n,cnt;
    int head[maxn];
    int siz[maxn],son[maxn],dep[maxn];
    int max_dep[maxs],dis[maxn];
    int ans[maxn];
    struct Edge{
    	int to,next;
    }e[maxn];
    void Aedge(int x,int y){
    	e[++cnt].to=y;
    	e[cnt].next=head[x];
    	head[x]=cnt;
    }
    void dfs1(int x){
    	siz[x]=1;
    	for(int i=head[x];i;i=e[i].next){
    		const rint y=e[i].to;
    		dis[y]^=dis[x],dep[y]=dep[x]+1;
    		dfs1(y);
    		siz[x]+=siz[y];
    		if(!son[x]||siz[y]>siz[son[x]]) son[x]=y;
    	}
    }
    void upd_ans(int rt,int x){
    	ans[rt]=max(ans[rt],max_dep[dis[x]]+dep[x]-dep[rt]*2);
    	for(int i=0;i<=21;++i) ans[rt]=max(ans[rt],max_dep[dis[x]^(1<<i)]+dep[x]-dep[rt]*2);
    	for(int i=head[x];i;i=e[i].next) upd_ans(rt,e[i].to);
    }
    void upd_max_dep(int x){
    	max_dep[dis[x]]=max(max_dep[dis[x]],dep[x]);
    	for(int i=head[x];i;i=e[i].next) upd_max_dep(e[i].to);
    }
    void cle(int x){
    	max_dep[dis[x]]=-INF;
    	for(int i=head[x];i;i=e[i].next) cle(e[i].to);
    }
    void dfs(int x,int op){
    	for(int i=head[x];i;i=e[i].next){
    		const rint y=e[i].to;
    		if(y!=son[x]) dfs(y,0),ans[x]=max(ans[x],ans[y]);
    	}
    	if(son[x]) dfs(son[x],1),ans[x]=max(ans[x],ans[son[x]]);
    	for(int i=head[x];i;i=e[i].next){
    		const rint y=e[i].to;
    		if(y!=son[x]) upd_ans(x,y),upd_max_dep(y);
    	}
    	ans[x]=max(ans[x],max_dep[dis[x]]-dep[x]);
    	for(int i=0;i<=21;++i) ans[x]=max(ans[x],max_dep[dis[x]^(1<<i)]-dep[x]);
    	max_dep[dis[x]]=max(max_dep[dis[x]],dep[x]);
    	if(!op) cle(x);
    }
    int main(){
    	//freopen("1.in","r",stdin);
    	memset(max_dep,-INF,sizeof max_dep);
    	scanf("%d",&n);
    	for(int i=2,x;i<=n;++i){
    		char ss;
    		scanf("%d %c",&x,&ss);
    		Aedge(x,i),dis[i]=1<<(ss-'a');
    	}
    	dfs1(1);
    	dfs(1,0);
    	for(int i=1;i<=n;++i) printf("%d ",ans[i]);
    	printf("
    ");
    	return 0;
    }
    
  • 相关阅读:
    Problem E. Matrix from Arrays(杭电2018年多校第四场+思维+打表找循环节)
    Reachability from the Capital(Codeforces Round #490 (Div. 3)+tarjan有向图缩点)
    Network of Schools(POJ1326+有向图进行缩点)
    John's trip(POJ1041+欧拉回路+打印路径)
    Watchcow(POJ2230+双向欧拉回路+打印路径)
    Network(POJ3694+边双连通分量+LCA)
    Problem L. Visual Cube(杭电多校2018年第三场+模拟)
    floyd骚操作——传递闭包
    Remmarguts' Date(POJ2449+最短路+A*算法)
    Transformation(线段树+HDU4578+多种操作+鬼畜的代码)
  • 原文地址:https://www.cnblogs.com/Lour688/p/13887827.html
Copyright © 2011-2022 走看看