【题解】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)的更多相关文章

  1. 【DSU on tree】【CF741D】Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths

    Description 给定一棵 \(n\) 个节点的树,每条边上有一个字符,字符集大小 \(22\),求每个节点的子树内最长的简单路径使得路径上的字符经过重排后构成回文串. Limitation \ ...

  2. 【题解】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是可以用来处 ...

  3. CF741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths(dsu on tree)

    一棵根为1 的树,每条边上有一个字符(a-v共22种). 一条简单路径被称为Dokhtar-kosh当且仅当路径上的字符经过重新排序后可以变成一个回文串. 求每个子树中最长的Dokhtar-kosh路 ...

  4. dsu on tree (树上启发式合并) 详解

    一直都没出过算法详解,昨天心血来潮想写一篇,于是 dsu on tree 它来了 1.前置技能 1.链式前向星(vector 建图) 2.dfs 建树 3.剖分轻重链,轻重儿子 重儿子 一个结点的所有 ...

  5. 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,求每个子树中最长的边,满 ...

  6. UOJ#266. 【清华集训2016】Alice和Bob又在玩游戏 博弈,DSU on Tree,Trie

    原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ266.html 题解 首先我们可以直接暴力 $O(n^2)$ 用 sg 函数来算答案. 对于一个树就是枚举 ...

  7. dsu on tree入门

    先瞎扯几句 说起来我跟这个算法好像还有很深的渊源呢qwq.当时在学业水平考试的考场上,题目都做完了不会做,于是开始xjb出题.突然我想到这么一个题 看起来好像很可做的样子,然而直到考试完我都只想出来一 ...

  8. 洛谷P4482 [BJWC2018]Border 的四种求法 字符串,SAM,线段树合并,线段树,树链剖分,DSU on Tree

    原文链接https://www.cnblogs.com/zhouzhendong/p/LuoguP4482.html 题意 给定一个字符串 S,有 q 次询问,每次给定两个数 L,R ,求 S[L.. ...

  9. [学习笔记]Dsu On Tree

    [dsu on tree][学习笔记] - Candy? - 博客园 题单: 也称:树上启发式合并 可以解决绝大部分不带修改的离线询问的子树查询问题 流程: 1.重链剖分找重儿子 2.sol:全局用桶 ...

随机推荐

  1. js获取屏幕相关值

    <html><script>function a(){document.write("屏幕分辨率为:"+screen.width+"*" ...

  2. ural 1519 Formula 1(插头dp)

    1519. Formula 1 @ Timus Online Judge 干了一天啊!!!插头DP入门. 代码如下: #include <cstdio> #include <cstr ...

  3. console.log详细介绍

    console.log详细介绍 效果图: 代码如下: console.log("%c hello world!:http://www.baidu.com","color: ...

  4. 根据User Agent参数的各个字段Mozilla/5.0/4.0-AppleWebKit/Chrome/Safari/Firefox/Opera/MSIE来确定/判断客户端使用什么浏览器

    下面给你一一解答以及给你介绍: //Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN) AppleWebKit/533.21.1 (KHTML, like ...

  5. oracle用WHERE替代ORDER BY

    ORDER BY 子句只在两种严格的条件下使用索引. ORDER BY中所有的列必须包含在相同的索引中并保持在索引中的排列顺序. ORDER BY中所有的列必须定义为非空. WHERE子句使用的索引和 ...

  6. phpstudy2016安装redis扩展

    第一步:查看phpstudy版本 第二步:查看phpinfo信息,看Architecture所属类型. 第三步:下载redis扩展 去http://windows.php.Net/downloads/ ...

  7. html前端登录验证

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. git 提交添加 emoij 文字

    可能看到 git 提交是文本,就认为他无法使用表情图片,实际上 git 提交是可以添加表情 本文告诉大家如何做出下面图片提交 在 git 提交的时候,可以添加表情,只需要在字符串加上表示表情的文本 如 ...

  9. webpack学习(四)配置plugins

    1 plugins是什么??? 如果学过vue和react肯定知道生命周期函数,而生命周期函数实际上就是当程序运行在某个时刻一定会发生的函数. plugins其实也是如此,我们在项目中配置相应的plu ...

  10. 【图数据库】史上超全面的Neo4j使用指南

    转自:https://cloud.tencent.com/developer/article/1336299 在这篇文章中: 第一章:介绍 Neo4j是什么 Neo4j的特点 Neo4j的优点 第二章 ...