题目链接

\(Description\)

给定一棵树,每条边上有一个字符(a~v)。对每个节点,求它的子树中一条最长的路径,满足 路径上所有边上的字符可以重新排列成一个回文串。输出其最长长度。
\(n\leq 5\times10^5\)。

\(Solution\)

可以构成回文串,即要么所有字符都出现了偶数次,要么有一个出现了奇数次、其余都出现了偶数次。
转化为异或!把每个字符c(0~21)映射到1<<c上去。
令\(s[x]\)表示根节点到\(x\)路径上边权的异或和。那么路径\((u,v)\)满足条件当且仅当\(s[u]\ xor\ s[v]\)等于\(0\)或是某个二次幂。
而路径\((u,v)\)的答案是\(dep[u]+dep[v]-dep[LCA]*2\)。在LCA处计算,这样只需要对每个状态求它最大的\(dep\)。
而且更新时只有23种方式(对于\(s[v]\),可以从\(\max\{dep[s[v]]\}\)和\(\max\{dep[s[v]\ xor\ 2^i]\}\)更新)。
dsu on tree求每个子树的\(\max\{dep[s]\}\)就好了。
复杂度\(O(23n\log n)\)。

//608ms 79100KB
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#define gc() getchar()
#define MAXIN 300000
//#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
typedef long long LL;
const int N=5e5+5,INF=0x3f3f3f3f;int Enum,H[N],nxt[N],to[N],ch[N],s[N],f[(1<<22)+2],L[N],R[N],A[N],dep[N],sz[N],son[N],Ans[N];
char IN[MAXIN],*SS=IN,*TT=IN;inline int read()
{int now=0;register char c=gc();for(;!isdigit(c);c=gc());for(;isdigit(c);now=now*10+c-'0',c=gc());return now;
}
inline void AE(int u,int v,int c)
{to[++Enum]=v, nxt[Enum]=H[u], ch[Enum]=c, H[u]=Enum;
}
void DFS1(int x)
{static int Index=0;A[L[x]=++Index]=x;int mx=0; sz[x]=1;for(int i=H[x],v; i; i=nxt[i])dep[v=to[i]]=dep[x]+1, s[v]=s[x]^ch[i], DFS1(v), sz[x]+=sz[v], sz[v]>mx&&(mx=sz[v],son[x]=v);R[x]=Index;
}
inline int Add(int s,int d,int delta)
{int ans=f[s]+d-delta;for(int i=0; i<22; ++i) ans=std::max(ans,f[s^(1<<i)]+d-delta);//d[u]+d[v]-d[LCA]*2return ans;
}
void DFS2(int x,int keep)
{int ans=0;for(int i=H[x]; i; i=nxt[i]) if(to[i]!=son[x]) DFS2(to[i],0),ans=std::max(ans,Ans[to[i]]);if(son[x]) DFS2(son[x],1),ans=std::max(ans,Ans[son[x]]);ans=std::max(ans,Add(s[x],0,dep[x])), f[s[x]]=std::max(f[s[x]],dep[x]);for(int i=H[x],v,delta=dep[x]<<1; i; i=nxt[i])if((v=to[i])!=son[x]){for(int j=L[v]; j<=R[v]; ++j) ans=std::max(ans,Add(s[A[j]],dep[A[j]],delta));for(int j=L[v]; j<=R[v]; ++j) f[s[A[j]]]=std::max(f[s[A[j]]],dep[A[j]]);}Ans[x]=ans;if(!keep) for(int i=L[x]; i<=R[x]; ++i) f[s[A[i]]]=-INF;
}int main()
{int n=read();for(int i=2,x,c; i<=n; ++i){x=read(),c=gc(); while(!isalpha(c)) c=gc();AE(x,i,1<<c-'a');}memset(f,-0x3f,sizeof f);//没有的值不能用0更新 DFS1(1), DFS2(1,1);for(int i=1; i<=n; ++i) printf("%d ",Ans[i]);return 0;
}

转载于:https://www.cnblogs.com/SovietPower/p/10017233.html

Codeforces.741D.Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths(dsu on tree 思路)相关推荐

  1. [Codeforces741D]Arpa's letter-marked tree and Mehrdad's Dokhtar-kosh paths——dsu on tree

    题目链接: Codeforces741D 题目大意:给出一棵树,根为$1$,每条边有一个$a-v$的小写字母,求每个点子树中的一条最长的简单路径使得这条路径上的边上的字母重排后是一个回文串. 显然如果 ...

  2. Codeforces 741 D - Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths

    D - Arpa's letter-marked tree and Mehrdad's Dokhtar-kosh paths 思路: 树上启发式合并 从根节点出发到每个位置的每个字符的奇偶性记为每个位 ...

  3. Codeforces Round #383 (Div. 1): D. Arpa’s letter-marked tree…(dsu on tree+状压)

    题意: 给你一棵n个节点的树,每条边都代表着一个字母(a~v),对于每个节点u,求出以u为根的子树中有多少条路径满足:路径上的字符重新排列后可以得到一个回文字符串 思路: 前置:dsu on tree ...

  4. 【CodeForces】741 D. Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths(dsu on tree)

    [题意]给定n个点的树,每条边有一个小写字母a~v,求每棵子树内的最长回文路径,回文路径定义为路径上所有字母存在一种排列为回文串.n<=5*10^5. [算法]dsu on tree [题解]这 ...

  5. CF741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths

    CF741D Arpa's letter-marked tree and Mehrdad's Dokhtar-kosh paths 好像这个题只能Dsu On Tree? 有根树点分治 统计子树过x的 ...

  6. Codeforces 600E. Lomsat gelral(Dsu on tree学习)

    题目链接:http://codeforces.com/problemset/problem/600/E n个点的有根树,以1为根,每个点有一种颜色.我们称一种颜色占领了一个子树当且仅当没有其他颜色在这 ...

  7. dsu on tree(Educational Codeforces Round 2: E. Lomsat gelral)

    题意: 一棵n个节点的树,每个节点都有一种颜色,如果颜色c在以u为根的子树中出现的次数大于等于一半,那么这个颜色就是u节点的支配色, 因为是大于等于,所以一个节点的支配色可能不止一种,求出每个节点的支 ...

  8. 2020 China Collegiate Programming Contest Changchun F - Strange Memory(dsu on tree + 位运算小技巧)

    题目连接: https://codeforces.com/gym/102832/problem/F 首先写这个题的时候要注意内存的问题 不要瞎几把define int long long 题解: 考虑 ...

  9. 阔力梯的树(2020 CCPC Wannafly Winter Camp Day2 Div.12 )dsu on tree

    题解: dsu on tree dsu on tree的基本步骤就不说了 看到这题询问结点的子树问题,而且询问时离线的,首先想到的dsu on tree的这个trick. 本题的难题就是如何维护结点所 ...

  10. CF375D Tree and Queries(dsu on tree)

    题解: 个人感觉这个题目是一个挺不错的题的.(这里就不说dsu on tree的这个过程是什么了) 我们在dsu on tree计算答案时需要有一个小小技巧去优化一下时间复杂度. 就是当我们用一个cn ...

最新文章

  1. UILayer的一些属性
  2. 单片机流星灯_51单片机拖尾灯实现
  3. rabbitmq php 学习
  4. SDUT ACM 2144 最小生成树,克鲁斯卡尔模板
  5. 下一代网络安全将全部基于行为识别
  6. android 获取数组大小,看得见的数据结构Android版之数组表(数据结构篇)
  7. 端到端加密优缺点_基于Filecoin的去中心化文件保存和加密分享平台
  8. 嵌入式Linux系统编程学习之二十八线程的等待退出
  9. 传感器 倾斜角 android,android – 如何使用sensor / s获得手机的角度/度数?
  10. 第六节:变量-可变变量
  11. 页面跳转_PyQt5多页面跳转
  12. 一文教你如何解决TXC晶振工作不正常的问题
  13. HTC全景视频,2D 3D视频播放器下载教程
  14. mysql连接本地数据库失败_“sql server”连接本地数据库失败怎么办?
  15. autocad html 插件,cad插件有哪些
  16. 【工作笔记】从零开始学ExtJs6(四)—— 常用api小记
  17. 南开100题计算机三级数据库,全国计算机三级数据库技术南开100题.doc
  18. 十行Python代码替换证件照背景颜色
  19. 十大【C语言】经典书籍,应该有你看过的吧
  20. python列表左闭右开_python中的细节—左闭右开原则

热门文章

  1. [JDK8] Lambda
  2. android 学习随笔二十三(动画:Fragment )
  3. Oracle study之--HASH Cluster特点
  4. 我与51CTO的战争之值得尊敬的对手
  5. 如何学习自然语言处理(转)
  6. 今天又感受到了编程的乐趣
  7. rz/sz安装与乱码问题
  8. java计算一个日子距离_java计算两地距离(公里)
  9. java 多环境 虚拟环境_Spring profile通过多种方法实现多环境支持
  10. python面值组合_算法题 - 拼凑面额 - Python