【CF741D】Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths(dsu on tree)
题意:我们称一个字符串为周驿东串当且仅当重排它的字符可以组成一个回文串。
给出一个n个点的有根树,根为1,每条边上有一个从a到v的字符,求每个点的子树中所有简单路径可以组成的周驿东串中的最长长度。
n<=5e5
思路:https://www.cnblogs.com/zzqsblog/p/6146916.html
一个串为周驿东串当且仅当其中只有0/1个字符出现奇数次
将每个字母看成一个二进制位,设s[i]为根到i的边权xor和,对于固定的点x要在其子树中找到来自不同分支的a和b使得s[a]^s[b]为0或者2的次幂,且dep[a]+dep[b]-2*dep[x]最大
s[a]^s[b]的条件等价于s[a]=s[b]或者s[a]和s[b]只有1位不同
lca直接当做x算实际上的dep应该比算dep[x]大,答案会变大,需要先统计再更新
- #include<bits/stdc++.h>
- using namespace std;
- typedef long long ll;
- typedef unsigned int uint;
- typedef unsigned long long ull;
- typedef pair<int,int> PII;
- typedef pair<ll,ll> Pll;
- typedef vector<int> VI;
- typedef vector<PII> VII;
- typedef pair<ll,int>P;
- #define N 500010
- #define M 1000010
- #define fi first
- #define se second
- #define MP make_pair
- #define pi acos(-1)
- #define mem(a,b) memset(a,b,sizeof(a))
- #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
- #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
- #define lowbit(x) x&(-x)
- #define Rand (rand()*(1<<16)+rand())
- #define id(x) ((x)<=B?(x):m-n/(x)+1)
- #define ls p<<1
- #define rs p<<1|1
- #define S 1<<22
- const ll MOD=1e9+,inv2=(MOD+)/;
- double eps=1e-;
- int INF=<<;
- ll inf=5e13;
- int dx[]={-,,,};
- int dy[]={,,-,};
- char ch[];
- int head[N],vet[M],nxt[M],len[M],tot;
- int son[N],dep[N],s[N],size[N],skip;
- int ans[N],mxdep[<<],now,t;
- int read()
- {
- int v=,f=;
- char c=getchar();
- while(c<||<c) {if(c=='-') f=-; c=getchar();}
- while(<=c&&c<=) v=(v<<)+v+v+c-,c=getchar();
- return v*f;
- }
- void add(int a,int b,int c)
- {
- nxt[++tot]=head[a];
- vet[tot]=b;
- len[tot]=c;
- head[a]=tot;
- }
- void dfs1(int u,int fa)
- {
- size[u]=;
- int e=head[u];
- while(e)
- {
- int v=vet[e];
- if(v!=fa)
- {
- dep[v]=dep[u]+;
- s[v]=s[u]^len[e];
- dfs1(v,u);
- size[u]+=size[v];
- if(size[v]>size[son[u]]) son[u]=v;
- }
- e=nxt[e];
- }
- }
- void clr(int u)
- {
- mxdep[s[u]]=-INF;
- }
- void update(int u)
- {
- t=max(t,mxdep[s[u]]+dep[u]-now*);
- rep(i,,) t=max(t,mxdep[s[u]^(<<i)]+dep[u]-now*);
- }
- void ins(int u)
- {
- mxdep[s[u]]=max(mxdep[s[u]],dep[u]);
- }
- void solve(int u,int fa,int op)
- {
- if(op==) clr(u);
- if(op==) update(u);
- if(op==) ins(u);
- int e=head[u];
- while(e)
- {
- int v=vet[e];
- if(v!=fa&&v!=skip) solve(v,u,op);
- e=nxt[e];
- }
- }
- void dfs2(int u,int fa,int op)
- {
- int e=head[u];
- while(e)
- {
- int v=vet[e];
- if(v!=fa&&v!=son[u]) dfs2(v,u,);
- e=nxt[e];
- }
- if(son[u])
- {
- dfs2(son[u],u,);
- skip=son[u];
- }
- now=dep[u];
- e=head[u];
- while(e)
- {
- int v=vet[e];
- if(v!=fa) ans[u]=max(ans[u],ans[v]);
- e=nxt[e];
- }
- e=head[u];
- while(e)
- {
- int v=vet[e];
- if(v!=fa&&v!=son[u])
- {
- solve(v,u,);
- solve(v,u,);
- }
- e=nxt[e];
- }
- update(u);
- ins(u);
- ans[u]=max(ans[u],t);
- skip=;
- if(!op)
- {
- solve(u,fa,);
- t=-INF;
- }
- }
- int main()
- {
- //freopen("1.in","r",stdin);
- //freopen("1.out","w",stdout);
- rep(i,,S) mxdep[i]=-INF;
- int n=read();
- tot=;
- rep(i,,n)
- {
- int x;
- scanf("%d%s",&x,ch);
- add(x,i,<<(ch[]-'a'));
- add(i,x,<<(ch[]-'a'));
- }
- skip=t=now=;
- dfs1(,);
- dfs2(,,);
- rep(i,,n) printf("%d ",ans[i]);
- return ;
- }
【CF741D】Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths(dsu on tree)的更多相关文章
- 【DSU on tree】【CF741D】Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths
Description 给定一棵 \(n\) 个节点的树,每条边上有一个字符,字符集大小 \(22\),求每个节点的子树内最长的简单路径使得路径上的字符经过重排后构成回文串. Limitation \ ...
- 【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 [题解]这 ...
- 【cf741】D. Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths(dsu on tree)
传送门 题意: 给出一颗以\(1\)为根的有根树,树边带有一个字符(\(a\)~\(v\))的信息. 输出对于每个结点,其子树内最长的简单路径并且满足边上的字符能够组成回文串. 思路: 显然最终的答案 ...
- CF741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths(dsu on tree)
一棵根为1 的树,每条边上有一个字符(a-v共22种). 一条简单路径被称为Dokhtar-kosh当且仅当路径上的字符经过重新排序后可以变成一个回文串. 求每个子树中最长的Dokhtar-kosh路 ...
- Codeforces 741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths(dsu on tree)
感觉dsu on tree一定程度上还是与点分类似的.考虑求出跨过每个点的最长满足要求的路径,再对子树内取max即可. 重排后可以变成回文串相当于出现奇数次的字母不超过1个.考虑dsu on tree ...
- 【Apache】HTTPD 2.4.37 + OpenSSL 1.1.1 企业级安全配置(含TLS修复)
我为什么要写这一篇稿子? 为了避免更多的运维.开发者没能实现企业的信息安全,我将共享出我个人的HTTPD的安全修复(2.2和2.4差不太多就看2.4就好) 起因:我为某M工作,但因某M和testin合 ...
- 【开源】SoDiaoEditor 可能是目前最好用的开源电子病历编辑器(B/S架构)
此刻我的内心是忐忑的,这个标题给了我很大的压力,虽然很久以前我就在github上搜索一圈了,也没发现有其他更好的开源电子病历编辑器,如各位亲发现有更好的,烦请知会我一声. 该编辑器其实已经憋了很久了, ...
- 【转】【UML】使用Visual Studio 2010 Team System中的架构师工具(设计与建模)
Lab 1: 应用程序建模 实验目标 这个实验的目的是展示如何在Visual Studio 2010旗舰版中进行应用程序建模.团队中的架构师会通过建模确定应用程序是否满足客户的需求. 你可以创建不同级 ...
- 【Unity3D】Unity3D开发《我的世界》之六、创建地形(视频 + 源码)
转载请注明出处:http://www.cnblogs.com/shamoyuu/p/unity_minecraft_06.html 一.引入LibNoise 虽然Unity3D里也有一个Mathf.P ...
随机推荐
- CDN:目录
ylbtech-CDN:目录 1. 前端开源项目返回顶部 1. http://www.bootcdn.cn/ 2. https://www.npmjs.com/ 3. 2.返回顶部 3.返回顶部 ...
- java切分查询数据库表
在实际应用中,我经常用到遇到根据单号查询,单号又是批量如1000个单号,直接1000个in子查询是不行的,子查询是用上限的.如果表中数据达到上百万以上.即使有单号字段有索引查询也是很慢.这时可以用切分 ...
- CEF3 命令行 CefCommandLine 所有选项 与 开发中使用的测试网址
转自: https://blog.csdn.net/xiezhongyuan07/article/details/86640413 1.cef3 commandLine设置 在cef3开发过程中,在O ...
- MySQL 查询语句--------------进阶9:联合查询
#进阶9:联合查询 /* union 联合 合并:将多条查询语句的结果合并成一个结果 语法: 查询语句1 union 查询语句2 union..... 应用场景:要查询的结果来自于多个表,且多个表没有 ...
- socketpair
与pipe的区别 pipe产生的文件描述符是半双工的,需要pipe两次才能实现全双工,产生的两个描述符是一个读,一个写 socketpair直接就可以全双工,产生的两个文件描述符的任何一个都可读可写 ...
- python常用模块(3)
hashlib模块 hashlib提供了常见的摘要算法,如md5和sha1等等. 那么什么是摘要算法呢?摘要算法又称为哈希算法.散列算法.它通过一个函数,把任意长度的数据转换为一个长度固定的数据串(通 ...
- vsphere虚拟化之 DNS服务的创建(二)
1.创建域控的DNS服务器,打开"服务器管理器",由此可以看到AD域安装成功后,DNS服务也附带安装成功. 2.点击“工具”--“DNS” 3.点击“正向查询区域”--“best. ...
- 2019牛客暑期多校训练营(第二场) - H - Second Large Rectangle - dp
https://ac.nowcoder.com/acm/contest/882/H 正确的办法:dp1[i][j]表示以i,j为底的矩形的高.得到dp1之后,dp2[i][j]表示以dp1[i][j] ...
- 【问题解决方案】Markdown正文中慎用星号否则容易变斜体
参考链接: [学习总结]Markdown 使用的正确姿势:第九部分-斜体and加粗 原理: 注意: Markdown中,若在正文中使用星号,如乘号或者指针的星号时,需要特别注意 当一句话中包含两个或者 ...
- SELECT - 从表或视图中取出若干行
SYNOPSIS SELECT [ ALL | DISTINCT [ ON ( expression [, ...] ) ] ] * | expression [ AS output_name ] [ ...