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;
    }
    
  • 相关阅读:
    Flink-v1.12官方网站翻译-P020-Builtin Watermark Generators
    Flink-v1.12官方网站翻译-P019-Generating Watermarks
    Flink-v1.12官方网站翻译-P018-Event Time
    Flink-v1.12官方网站翻译-P017-Execution Mode (Batch/Streaming)
    Flink-v1.12官方网站翻译-P016-Flink DataStream API Programming Guide
    Flink-v1.12官方网站翻译-P015-Glossary
    Flink-v1.12官方网站翻译-P014-Flink Architecture
    Flink-v1.12官方网站翻译-P013-Timely Stream Processing
    Flink-v1.12官方网站翻译-P012-Stateful Stream Processing
    02-算法分析
  • 原文地址:https://www.cnblogs.com/Lour688/p/13887827.html
Copyright © 2011-2022 走看看