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;
    }
    
  • 相关阅读:
    把影响集中到一个点
    How to avoid Over-fitting using Regularization?
    适定性问题
    Numerical Differentiation 数值微分
    What Every Computer Scientist Should Know About Floating-Point Arithmetic
    Generally a good method to avoid this is to randomly shuffle the data prior to each epoch of training.
    What is the difference between iterations and epochs in Convolution neural networks?
    Every norm is a convex function
    Moore-Penrose Matrix Inverse 摩尔-彭若斯广义逆 埃尔米特矩阵 Hermitian matrix
    perl 类里的函数调用其他类的函数
  • 原文地址:https://www.cnblogs.com/Lour688/p/13887827.html
Copyright © 2011-2022 走看看