【题解】CF741D(DSU on TREE)
【题解】CF741D(DSU on TREE)
写一写这道题来学习学习模板
用二进制来转换一下条件,现在就是要求一下\(lowbit(x)=x\)的那些路径了。
DSU on TREE 是这样一种算法:
- 像树剖一样分出轻重链,根据那套理论可知轻边\(O(\log n)\)。
- 递归处理一个节点的所有轻儿子,并且回溯的时候将统计信息清空。
- 递归处理一个节点的那个重儿子,并且回溯的时候保留统计信息。
- 获得重儿子信息后,遍历一下所有轻儿子统计答案。
分析复杂度:对于每个点,可以被他父亲所有的轻边多遍历一次。复杂度\(O(tn \log n)\),\(t\)是加入一个信息需要的复杂度。
具体到这道题的话,就是开桶记录该二进制状态下最深深度点的深度。取\(max\)就好
//@winlere
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std; typedef long long ll;
inline int qr(){
register int ret=0,f=0;
register char c=getchar();
while(c<48||c>57)f|=c==45,c=getchar();
while(c>=48&&c<=57) ret=ret*10+c-48,c=getchar();
return f?-ret:ret;
}
char c;
const int maxn=5e5+5,inf=1e9;
int d[maxn],cnt[1<<22|1],n,siz[maxn],son[maxn],dfn[maxn],End[maxn],arc[maxn];
int ans[maxn],dis[maxn];
vector< pair<int,int> > e[maxn];
inline void add(const int&fr,const int&to,const int&w){
e[fr].push_back({to,1<<w});
}
void predfs(const int&now){
siz[now]=1;
dfn[now]=++*dfn;
arc[*dfn]=now;
for(auto t:e[now])
d[t.first]=d[now]^t.second,dis[t.first]=dis[now]+1,predfs(t.first),siz[now]+=siz[t.first],son[now]=siz[t.first]>siz[son[now]]?t.first:son[now];
End[now]=*dfn;
}
void dfs(const int&now,const int&keep){
for(auto t:e[now])
if(t.first^son[now])
dfs(t.first,0),ans[now]=max(ans[now],ans[t.first]);
if(son[now]) dfs(son[now],1),ans[now]=max(ans[now],ans[son[now]]);
if(cnt[d[now]]) ans[now]=max(ans[now],cnt[d[now]]-dis[now]);
for(int t=0;t<22;++t)
if(cnt[d[now]^(1<<t)])
ans[now]=max(ans[now],cnt[d[now]^(1<<t)]-dis[now]);
cnt[d[now]]=max(cnt[d[now]],dis[now]);
for(auto T:e[now])
if(T.first^son[now]){
for(int t=dfn[T.first];t<=End[T.first];++t){
if(cnt[d[arc[t]]])
ans[now]=max(ans[now],cnt[d[arc[t]]]+dis[arc[t]]-dis[now]*2);
for(int i=0;i<22;++i)
if(cnt[d[arc[t]]^(1<<i)])
ans[now]=max(ans[now],cnt[d[arc[t]]^(1<<i)]+dis[arc[t]]-dis[now]*2);
}
for(int t=dfn[T.first];t<=End[T.first];++t)
cnt[d[arc[t]]]=max(cnt[d[arc[t]]],dis[arc[t]]);
}
if(!keep) for(int t=dfn[now];t<=End[now];++t) cnt[d[arc[t]]]=0;
}
int main(){
n=qr();
for(int t=2,t1;t<=n;++t){
t1=qr();
char c=getchar();
while(c<'a'||c>'z') c=getchar();
add(t1,t,c-'a');
}
predfs(1);
dfs(1,0);
for(int t=1;t<=n;++t) printf("%d ",ans[t]);
putchar('\n');
return 0;
}
【题解】CF741D(DSU on TREE)的更多相关文章
- 【DSU on tree】【CF741D】Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths
Description 给定一棵 \(n\) 个节点的树,每条边上有一个字符,字符集大小 \(22\),求每个节点的子树内最长的简单路径使得路径上的字符经过重排后构成回文串. Limitation \ ...
- 【题解】Arpa's letter-marked tree and Mehrdad's Dokhtar-kosh paths Codeforces 741D DSU on Tree
Prelude 很好的模板题. 传送到Codeforces:(* ̄3 ̄)╭ Solution 首先要会DSU on Tree,不会的看这里:(❤ ω ❤). 众所周知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路 ...
- dsu on tree (树上启发式合并) 详解
一直都没出过算法详解,昨天心血来潮想写一篇,于是 dsu on tree 它来了 1.前置技能 1.链式前向星(vector 建图) 2.dfs 建树 3.剖分轻重链,轻重儿子 重儿子 一个结点的所有 ...
- CF 741D. Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths [dsu on tree 类似点分治]
D. Arpa's letter-marked tree and Mehrdad's Dokhtar-kosh paths CF741D 题意: 一棵有根树,边上有字母a~v,求每个子树中最长的边,满 ...
- UOJ#266. 【清华集训2016】Alice和Bob又在玩游戏 博弈,DSU on Tree,Trie
原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ266.html 题解 首先我们可以直接暴力 $O(n^2)$ 用 sg 函数来算答案. 对于一个树就是枚举 ...
- dsu on tree入门
先瞎扯几句 说起来我跟这个算法好像还有很深的渊源呢qwq.当时在学业水平考试的考场上,题目都做完了不会做,于是开始xjb出题.突然我想到这么一个题 看起来好像很可做的样子,然而直到考试完我都只想出来一 ...
- 洛谷P4482 [BJWC2018]Border 的四种求法 字符串,SAM,线段树合并,线段树,树链剖分,DSU on Tree
原文链接https://www.cnblogs.com/zhouzhendong/p/LuoguP4482.html 题意 给定一个字符串 S,有 q 次询问,每次给定两个数 L,R ,求 S[L.. ...
- [学习笔记]Dsu On Tree
[dsu on tree][学习笔记] - Candy? - 博客园 题单: 也称:树上启发式合并 可以解决绝大部分不带修改的离线询问的子树查询问题 流程: 1.重链剖分找重儿子 2.sol:全局用桶 ...
随机推荐
- Python 基础 --初识Python
python的起源 python是一门 解释型弱类型编程语言. 特点: 简单.明确.优雅 python的解释器 CPython. 官方提供的. 内部使用c语言来实现 PyPy. 一次性把我们的代码解释 ...
- docfx 做一个和微软一样的文档平台
开发中,有一句话叫 最不喜欢的是写文档,最不喜欢的是看别人家代码没有文档.那么世界上文档写最 la 好 ji 的就是微软了,那么微软的api文档是如何做的?难道请了很多人去写文档? 实际上微软有工具用 ...
- oracle函数 CHR(n1)
[功能]:将ASCII 码转换为字符. [参数]:n1,为0 ~ 255,整数 [返回]:字符型 [示例] SQL> select chr(54740) zhao,chr(65) chr65 f ...
- oracle函数 ceil(x)
[功能]返回大于等于x的最小整数值 [参数]x,数字型表达式 [返回]数字 [示例] select ceil(3.1),ceil(2.8+1.3),ceil(0) from dual; 返回4,5,0
- MySQL 8.0 技术详解
MySQL 8.0 简介 MySQL 5.7 到 8.0,Oracle 官方跳跃了 Major Version 版本号,随之而来的就是在 MySQL 8.0 上做了许多重大更新,在往企业级数据库的路上 ...
- setTimeout 传参
一般setTimeout中的参数为 setTimeout(f,time)但是如果我想要给f函数传入一个参数怎么办 setTimeout(f(arguments),time) 如果我这样写的话,那么ti ...
- CODE FESTIVAL 2017 qual A D Four Coloring(补题)
这题看了好几天才看懂,一直误解题解中的d * d了 题解中说把大的格子划分成d * d的方格,我划分的时候把格子当作点来算的,一直觉得那明明是(d-1) * (d-1),昨天刚反映过来 思路:把格子旋 ...
- Project Euler Problem 7-10001st prime
素数线性筛 MAXN = 110100 prime = [0 for i in range(210000)] for i in range(2,MAXN): if prime[i] == 0: pri ...
- laravel5.*安装使用Redis以及解决Class 'Predis\Client' not found和Fatal error: Non-static method Redis::set() cannot be called statically错误
https://phpartisan.cn/news/35.html laravel中我们可以很简单的使用Redis,如何在服务器安装Redis以及原创访问你们可以访问Ubuntu 设置Redis密码 ...
- poj 3295
题目意思就是计算表达式的值,如果所有情况下表达式为真就输出“tautology”,否则输出“not”. p, q, r, s, and t,每个人有两种情况,综合起来一共有32种情况,枚举所有情况最后 ...