CF741DArpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths(DSU on tree)
题目大意:
给定一个以1为根的树,每条路径上都有一个字符(a~v共22个)询问对于每一个子树内最长的路径上字母经排序后可以形成回文串的最长路径多长
解题思路:
假定给你一个字符串,如何判定其经打乱能否形成回文串,那就是说所有字符中最多只有一个能出现奇数次,22个字符,可以用2进制表示每个字符出现的次数奇偶性,1为奇0为偶,那么处理出一个点到根节点路径上的异或和(设为xi),如果两个节点i,j的xi=xj那么就说明这两个点的路径上符合要求。
暴力的思路:暴力搜索一棵树中所有的xi看看有没有相同或差一位的再进行答案更新。
考虑优化,既然是不同子树中的点,那么就可以用一个数组存起来异或和为x的最大深度maxdeep[x],每次进去找,找完再把整颗子树推进去。这样就是O(n2)
这样就可以用DSU了,每次处理子树时,最后处理重儿子,非重儿子直接推倒,在更新上层时直接在重儿子版本上构建数组,再重建轻儿子,注意更新答案时要更新为子树最大值,跨字数最大值,返祖链最大值中的最大值。时间复杂度O(nlogn)
DSU还是十分优秀啊
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
struct pnt{
int hd;
int dp;
int wgt;
int mxs;
int ans;
int xr;
}p[];
struct ent{
int twd;
int lst;
int vls;
}e[];
int n;
int cnt;
char cmd[];
int mxdp[];
void ade(int f,int t,int v)
{
cnt++;
e[cnt].twd=t;
e[cnt].lst=p[f].hd;
e[cnt].vls=v;
p[f].hd=cnt;
}
void Basic_dfs(int x,int f)
{
p[x].dp=p[f].dp+;
p[x].wgt=;
int maxs=-;
for(int i=p[x].hd;i;i=e[i].lst)
{
int to=e[i].twd;
p[to].xr=p[x].xr^e[i].vls;
Basic_dfs(to,x);
p[x].wgt+=p[to].wgt;
if(maxs<p[to].wgt)
{
maxs=p[to].wgt;
p[x].mxs=to;
}
}
}
void Build_dfs(int x)
{
mxdp[p[x].xr]=std::max(mxdp[p[x].xr],p[x].dp);
for(int i=p[x].hd;i;i=e[i].lst)
Build_dfs(e[i].twd);
}
void Destory_dfs(int x)
{
mxdp[p[x].xr]=;
for(int i=p[x].hd;i;i=e[i].lst)
Destory_dfs(e[i].twd);
}
void Ans_dfs(int x,int a)
{
if(mxdp[p[x].xr])
p[a].ans=std::max(p[a].ans,p[x].dp+mxdp[p[x].xr]-*p[a].dp);
for(int i=;i<;i++)
{
int tmp=<<i;
if(mxdp[p[x].xr^tmp])
p[a].ans=std::max(p[a].ans,p[x].dp+mxdp[p[x].xr^tmp]-*p[a].dp);
}
for(int i=p[x].hd;i;i=e[i].lst)
Ans_dfs(e[i].twd,a);
}
void DSU_dfs(int x,bool hvs)
{
for(int i=p[x].hd;i;i=e[i].lst)
{
int to=e[i].twd;
if(to==p[x].mxs)
continue;
DSU_dfs(to,false);
p[x].ans=std::max(p[x].ans,p[to].ans);
}
if(p[x].mxs)
{
DSU_dfs(p[x].mxs,true);
p[x].ans=std::max(p[x].ans,p[p[x].mxs].ans);
}
if(mxdp[p[x].xr])
p[x].ans=std::max(p[x].ans,mxdp[p[x].xr]-p[x].dp);
for(int i=;i<;i++)
{
int tmp=<<i;
if(mxdp[p[x].xr^tmp])
p[x].ans=std::max(p[x].ans,mxdp[p[x].xr^tmp]-p[x].dp);
}
mxdp[p[x].xr]=std::max(p[x].dp,mxdp[p[x].xr]);
for(int i=p[x].hd;i;i=e[i].lst)
{
int to=e[i].twd;
if(to==p[x].mxs)
continue;
Ans_dfs(to,x);
Build_dfs(to);
}
if(hvs)
return ;
Destory_dfs(x);
}
int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++)
{
int x;
scanf("%d",&x);
scanf("%s",cmd);
int tmp=<<(cmd[]-'a');
ade(x,i,tmp);
}
Basic_dfs(,);
DSU_dfs(,true);
for(int i=;i<=n;i++)
printf("%d ",p[i].ans);
puts("");
return ;
}
CF741DArpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths(DSU on tree)的更多相关文章
- Codeforces 741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths(dsu on tree)
感觉dsu on tree一定程度上还是与点分类似的.考虑求出跨过每个点的最长满足要求的路径,再对子树内取max即可. 重排后可以变成回文串相当于出现奇数次的字母不超过1个.考虑dsu on tree ...
- 【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 [题解]这 ...
- CF741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths(dsu on tree)
一棵根为1 的树,每条边上有一个字符(a-v共22种). 一条简单路径被称为Dokhtar-kosh当且仅当路径上的字符经过重新排序后可以变成一个回文串. 求每个子树中最长的Dokhtar-kosh路 ...
- 【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)
题意:我们称一个字符串为周驿东串当且仅当重排它的字符可以组成一个回文串. 给出一个n个点的有根树,根为1,每条边上有一个从a到v的字符,求每个点的子树中所有简单路径可以组成的周驿东串中的最长长度. n ...
- 【CF600E】Lomsat gelral(dsu on tree)
[CF600E]Lomsat gelral(dsu on tree) 题面 洛谷 CF题面自己去找找吧. 题解 \(dsu\ on\ tree\)板子题 其实就是做子树询问的一个较快的方法. 对于子树 ...
- 【Luogu U41492】树上数颜色——树上启发式合并(dsu on tree)
(这题在洛谷主站居然搜不到--还是在百度上偶然看到的) 题目描述 给一棵根为1的树,每次询问子树颜色种类数 输入输出格式 输入格式: 第一行一个整数n,表示树的结点数 接下来n-1行,每行一条边 接下 ...
- CF375D Tree and Queries(dsu on tree)
思路 dsu on tree的板子,可惜人傻把 for(int i=fir[u];i;i=nxt[i]) 打成 for(int i=fir[u];i<=n;i++) 调了两个小时 这题要求维护& ...
- CF600E Lomsat gelral(dsu on tree)
dsu on tree跟冰茶祭有什么关系啊喂 dsu on tree的模板题 思想与解题过程 类似树链剖分的思路 先统计轻儿子的贡献,再统计重儿子的贡献,得出当前节点的答案后再减去轻儿子对答案的贡献 ...
随机推荐
- dubbo+zookeeper+springMVC +maven
pom: <dependency> <groupId>com.github.sgroschupf</grou ...
- vue中剖析中的一些方法
1 判断属性 71 -81 var hasOwnProperty = Object.prototype.hasOwnProperty; /** * Check whether the object h ...
- pigofzhou的巧克力棒
Description 众所周知,pigofzhou有许多妹子.有一天,pigofzhou得到了一根巧克力棒,他想把这根巧克力棒分给他的妹子们.具体地,这根巧克力棒长为 n,他想将这根巧克力棒折成 n ...
- Mark Compact GC (Part two :Two-Finger)
目录 Two-Finger算法 前提 概要 步骤一:移动对象 步骤二:更新指针 优缺点 表格算法 概要 步骤一:移动对象群 和 构筑间隙表格 移动对象群 构筑间隙表格 步骤二:更新指针 优缺点 Two ...
- python垃圾回收算法
标准python垃圾回收器由两部分组成,即引用计数回收器和分代垃圾回收器(即python包中的gc module).其中,引用计数模块不能被禁用,而GC模块可以被禁用. 引用计数算法 python中每 ...
- 使用scatter画散点图
刚开始接触Python,照着例子写的代码,百度注释的. from numpy import * import matplotlib import matplotlib.pyplot as plt im ...
- 树莓派开机运行Python脚本 控制LED灯闪烁
一.新建一个开机运行文件 在 /home/pi/.config 下创建一个文件夹,名称为 autostart,并在该文件夹下创建一个led.desktop文件(文件名以.desktop结尾) 编辑le ...
- JS 中 this 与闭包的结合产生的问题
代码片段一: var name = "The Window"; var object = { name : "My Object", getNameFunc : ...
- RocketMQ 就是耗内存
http://blog.csdn.net/loongshawn/article/details/51086876 https://rocketmq.incubator.apache.org/docs/ ...
- ArcGIS Engine中的重点类库介绍
转自原文ArcGIS Engine中的重点类库介绍 System类库 System类库是ArcGIS体系结构中最底层的类库.System类库包含给构成ArcGIS的其他类库提供服务的组件.System ...