【题解】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:全局用桶 ...
随机推荐
- HDFS概念名称节点和数据节点-基本模型
- @bzoj - 4380@ [POI2015] Myjnie
目录 @description@ @solution@ @accepted code@ @details@ @description@ 有 n 家洗车店从左往右排成一排,每家店都有一个正整数价格 p[ ...
- USDT钱包安装
安装USDT钱包 wget https://bintray.com/artifact/download/omni/OmniBinaries/omnicore-0.4.0-x86_64-linux-gn ...
- 受控组件 & 非受控组件
在 React 中表单组件可分为两类,受控与非受控组件. 一. 受控组件 设置了 value 的 <input> 是一个受控组件. 对于受控的 <input>,渲染出来的 HT ...
- Java安装完毕后的环境配置
右键计算机=>属性=>高级系统设置=>环境变量=>系统变量=>新建系统变量 变量名:JAVA_HOME变量值:E:\Program Files\Java\jdk-9.0. ...
- poj 3675 Telescope (圆与多边形面积交)
3675 -- Telescope 再来一题.这题的代码还是继续完全不看模板重写的. 题意不解释了,反正就是一个单纯的圆与多边形的交面积. 这题的精度有点搞笑.我用比较高的精度来统计面积,居然wa了. ...
- input标签前台实现文件上传
值得注意的是:当一个表单里面包含这个上传元素的时候,表单的enctype必须指定为multipart/form-data,method必须指定为post,浏览器才会认识并正确执行.但是还有一点,浏览器 ...
- [ Laravel 5.1 文档 ] 服务 —— 帮助函数
http://laravelacademy.org/post/205.html 1.简介 Laravel自带了一系列PHP帮助函数,很多被框架自身使用,然而,如果你觉得方便的话也可以在应用中随心所欲的 ...
- python命令之m参数
在命令行中使用python时,python支持在其后面添加可选参数. python命令的可选参数有很多,例如:使用可选参数h可以查询python的帮助信息: 可选参数m 下面我们来说说python命令 ...
- 零基础入门--中文命名实体识别(BiLSTM+CRF模型,含代码)
自己也是一个初学者,主要是总结一下最近的学习,大佬见笑. 中文分词说到命名实体抽取,先要了解一下基于字标注的中文分词.比如一句话 "我爱北京天安门”. 分词的结果可以是 “我/爱/北京/天安 ...