Lomsat gelral

一棵以\(1\)为根的树有\(n\)个结点,每个结点都有一种颜色,每个颜色有一个编号,求树中每个子树的最多的颜色编号(若有数量一样的,则求编号和)。

\(n \le 10^5\)

题解

dsu on tree模板题。

暴力做法其实很简单,就是枚举这个点,然后扫一遍子树得到答案,然后清空cnt数组。

我们会发现它做了一些无用功,比如说最后一次清空,其实可以用于他的父节点,这样父节点就可以少算一个子节点。

我们想让尽量大的子树不擦除,那么就树剖剖出重儿子,重儿子不擦除就可以了。

这样一个点会被祖先统计到当且仅当它在轻儿子子树中,所以一个点被统计不超过\(O(\log n)\)次。总时间复杂度\(O(n\log n)\)。

  1. #include<bits/stdc++.h>
  2. #define co const
  3. #define il inline
  4. template<class T> T read(){
  5. T x=0,w=1;char c=getchar();
  6. for(;!isdigit(c);c=getchar())if(c=='-') w=-w;
  7. for(;isdigit(c);c=getchar()) x=x*10+c-'0';
  8. return x*w;
  9. }
  10. template<class T>il T read(T&x){
  11. return x=read<T>();
  12. }
  13. using namespace std;
  14. typedef long long LL;
  15. co int N=100001;
  16. int n,val[N];
  17. vector<int> e[N];
  18. int fa[N],siz[N],son[N];
  19. void dfs1(int x,int fa){
  20. siz[x]=1;
  21. for(unsigned i=0;i<e[x].size();++i){
  22. int y=e[x][i];
  23. if(y==fa) continue;
  24. ::fa[y]=x;
  25. dfs1(y,x);
  26. siz[x]+=siz[y];
  27. if(siz[y]>siz[son[x]]) son[x]=y;
  28. }
  29. }
  30. LL ans[N];
  31. int cnt[N],vis[N];
  32. int maxc;LL sum;
  33. void change(int x,int d){
  34. cnt[val[x]]+=d;
  35. if(d>0&&cnt[val[x]]>=maxc){
  36. if(cnt[val[x]]>maxc) sum=0,maxc=cnt[val[x]];
  37. sum+=val[x];
  38. }
  39. for(unsigned i=0;i<e[x].size();++i){
  40. int y=e[x][i];
  41. if(y==fa[x]||vis[y]) continue;
  42. change(y,d);
  43. }
  44. }
  45. void dfs2(int x,int use){
  46. for(unsigned i=0;i<e[x].size();++i){
  47. int y=e[x][i];
  48. if(y==fa[x]||y==son[x]) continue;
  49. dfs2(y,0);
  50. }
  51. if(son[x]) dfs2(son[x],1),vis[son[x]]=1;
  52. change(x,1),ans[x]=sum;
  53. if(son[x]) vis[son[x]]=0;
  54. if(!use) change(x,-1),maxc=sum=0;
  55. }
  56. int main(){
  57. read(n);
  58. for(int i=1;i<=n;++i) read(val[i]);
  59. for(int i=1,x,y;i<n;++i){
  60. read(x),read(y);
  61. e[x].push_back(y),e[y].push_back(x);
  62. }
  63. dfs1(1,0);
  64. dfs2(1,0);
  65. for(int i=1;i<=n;++i) printf("%lld ",ans[i]);
  66. return 0;
  67. }

Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths

一棵以\(1\)号点为根的树,每条边上有一个小写字母\(a\sim v\)。定义一条路经是好的,当且仅当这条路径上经过的所有小写字母重排后可以构成回文串。

求以每个点为根的子树中最长的好的路径。

\(n \le 10^5\)

题解

如果重排后能形成回文串,那么出现奇数次的字符最多有1个。

首先,对于一条字母是\(c\)的边,定义其权值为\(2^c\)。

这样一条路经是好的就当且仅当这条路径的异或和二进制位中的\(1\)的个数不超过\(1\)。

在处理以某一点为根的子树时,开桶,记\(f[i]\)表示到根路径异或和为\(i\)的点的最大深度,可以类似点分的方法计算答案并更新桶。

然后套个dsu on tree,这道题就解决了。时间复杂度\(O(n \log n)\)。

  1. #include<bits/stdc++.h>
  2. #define co const
  3. #define il inline
  4. template<class T> T read(){
  5. T x=0,w=1;char c=getchar();
  6. for(;!isdigit(c);c=getchar())if(c=='-') w=-w;
  7. for(;isdigit(c);c=getchar()) x=x*10+c-'0';
  8. return x*w;
  9. }
  10. template<class T>il T read(T&x){
  11. return x=read<T>();
  12. }
  13. using namespace std;
  14. co int N=500000+5;
  15. int n,nx[N],to[N],val[N];
  16. int siz[N],son[N],dep[N];
  17. int pos[N],dfn,id[N],lst[N];
  18. void dfs1(int x){
  19. siz[x]=1,id[pos[x]=++dfn]=x;
  20. for(int y=to[x];y;y=nx[y]){
  21. dep[y]=dep[x]+1,val[y]=val[y]^val[x];
  22. dfs1(y);
  23. siz[x]+=siz[y];
  24. if(siz[y]>siz[son[x]]) son[x]=y;
  25. }
  26. lst[x]=dfn;
  27. }
  28. int f[1<<22],ans[N];
  29. void dfs2(int x,int use){
  30. for(int y=to[x];y;y=nx[y])
  31. if(y!=son[x]) dfs2(y,0),ans[x]=max(ans[x],ans[y]);
  32. if(son[x]) dfs2(son[x],1),ans[x]=max(ans[x],ans[son[x]]);
  33. // cerr<<x<<" ans="<<ans[x]<<endl;
  34. if(f[val[x]]) ans[x]=max(ans[x],f[val[x]]-dep[x]);
  35. for(int i=0;i<22;++i)if(f[val[x]^(1<<i)])
  36. ans[x]=max(ans[x],f[val[x]^(1<<i)]-dep[x]);
  37. f[val[x]]=max(f[val[x]],dep[x]);
  38. // cerr<<x<<" ans="<<ans[x]<<endl;
  39. for(int y=to[x];y;y=nx[y])if(y!=son[x]){
  40. for(int i=pos[y];i<=lst[y];++i){
  41. int z=id[i];
  42. if(f[val[z]]) ans[x]=max(ans[x],f[val[z]]+dep[z]-(dep[x]<<1));
  43. for(int j=0;j<22;++j)if(f[val[z]^(1<<j)])
  44. ans[x]=max(ans[x],f[val[z]^(1<<j)]+dep[z]-(dep[x]<<1));
  45. }
  46. for(int i=pos[y];i<=lst[y];++i){
  47. int z=id[i];
  48. f[val[z]]=max(f[val[z]],dep[z]);
  49. }
  50. }
  51. // cerr<<x<<" ans="<<ans[x]<<endl;
  52. if(!use) for(int i=pos[x];i<=lst[x];++i) f[val[id[i]]]=0;
  53. }
  54. int main(){
  55. read(n);
  56. for(int i=2;i<=n;++i){
  57. int fa=read<int>();char ch=getchar();
  58. nx[i]=to[fa],to[fa]=i,val[i]=1<<(ch-'a');
  59. }
  60. dfs1(1);
  61. dfs2(1,0);
  62. for(int i=1;i<=n;++i) printf("%d ",ans[i]);
  63. return 0;
  64. }

CF600E Lomsat gelral 和 CF741D Dokhtar-kosh paths的更多相关文章

  1. CF600E Lomsat gelral 【线段树合并】

    题目链接 CF600E 题解 容易想到就是线段树合并,维护每个权值区间出现的最大值以及最大值位置之和即可 对于每个节点合并一下两个子节点的信息 要注意叶子节点信息的合并和非叶节点信息的合并是不一样的 ...

  2. CF600E Lomsat gelral(dsu on tree)

    dsu on tree跟冰茶祭有什么关系啊喂 dsu on tree的模板题 思想与解题过程 类似树链剖分的思路 先统计轻儿子的贡献,再统计重儿子的贡献,得出当前节点的答案后再减去轻儿子对答案的贡献 ...

  3. CF600E:Lomsat gelral(线段树合并)

    Description 一棵树有n个结点,每个结点都是一种颜色,每个颜色有一个编号,求树中每个子树的最多的颜色编号的和. Input 第一行一个$n$.第二行$n$个数字是$c[i]$.后面$n-1$ ...

  4. [CF600E]Lomsat gelral

    题意翻译 一棵树有n个结点,每个结点都是一种颜色,每个颜色有一个编号,求树中每个子树的最多的颜色编号的和. 线段树合并板子题,没啥难度,注意开long long 不过这题$dsu$ $on$ $tre ...

  5. dsu on tree(CF600E Lomsat gelral)

    题意 一棵树有n个结点,每个结点都是一种颜色,每个颜色有一个编号,求树中每个子树的最多的颜色编号的和. dsu on tree 用来解决子树问题 好像不能带修改?? 暴力做这个题,就是每次扫一遍子树统 ...

  6. cf600E. Lomsat gelral(dsu on tree)

    题意 题目链接 给出一个树,求出每个节点的子树中出现次数最多的颜色的编号和 Sol dsu on tree的裸题. 一会儿好好总结总结qwq #include<bits/stdc++.h> ...

  7. CF600E Lomsat gelral——线段树合并/dsu on tree

    题目描述 一棵树有$n$个结点,每个结点都是一种颜色,每个颜色有一个编号,求树中每个子树的最多的颜色编号的和. 这个题意是真的窒息...具体意思是说,每个节点有一个颜色,你要找的是每个子树中颜色的众数 ...

  8. CF600E Lomsat gelral (启发式合并)

    You are given a rooted tree with root in vertex 1. Each vertex is coloured in some colour. Let's cal ...

  9. CF600E Lomsat gelral 树上启发式合并

    题目描述 有一棵 \(n\) 个结点的以 \(1\) 号结点为根的有根树. 每个结点都有一个颜色,颜色是以编号表示的, \(i\) 号结点的颜色编号为 \(c_i\)​. 如果一种颜色在以 \(x\) ...

随机推荐

  1. python爬虫1

    1 网页结构 html:超文本标记语言------->类似人的鼻子耳朵,长在那里,大体骨架就是那个样子 css:层叠样式表------->这个是外观的深化,比如贴个双眼皮,橙色眼睛... ...

  2. Android Capabilities讲解

    1.Capabilities介绍 可以看下之前代码里面设置的capabilities DesiredCapabilities capabilities =newDesiredCapabilities( ...

  3. 在ensp上的进行的浮动路由

    原理 实验模拟内容 搭建实验拓扑 相关参数 其他设置端口ip都一样,serial也一样(三个路由器都要设置的) 简单测试一下连通性 下面我们分别在路由器上配置所在网段的静态路由 配置完之后我们来查看一 ...

  4. mysql在windows下的服务安装

    前提必须用管理员身份运行 1.删除Mysql服务,打开命令行,输入下面的指令 sc delete MySql 2.初始化一下数据,比如配置文件中设置了数据的存储路径,日志位置等:该命令必须用管理员身份 ...

  5. tetetet

    http://www.wuwenhui.cn/2623.html http://www.360doc.com/content/16/1104/09/36005694_603810507.shtml

  6. Java基础之(四)HashMap(jdk10)

    JDK1.7以前的HashMap jdk1.7中,当冲突时,在冲突的地址上生成一个链表,将冲突的元素的key,通过equals进行比较,相同即覆盖,不同则添加到链表上,此时如果链表过长,效率就会大大降 ...

  7. 手撕面试官系列(二):开源框架面试题Spring+SpringMVC+MyBatis

    文章首发于今日头条:https://www.toutiao.com/i6712324863006081549/ 前言 跳槽时时刻刻都在发生,但是我建议大家跳槽之前,先想清楚为什么要跳槽.切不可跟风,看 ...

  8. C++—多态与继承

    一.基本概念 1.类的继承,是新的类从已有类那里得到已有的特性.或从已有类产生新类的过程就是类的派生.原有的类称为基类或父类,产生的新类称为派生类或子类. 2.派生类的声明: class 派生类名:继 ...

  9. 电路板工艺中的NPTH和PTH

    今天收到PCB生产公司发来的工程咨询单 Q1:请问贵司资料中的沉头孔是做PTH沉头还是做NPTH沉头? 好吧,鄙人见识少,第一次听说PTH和NPTH,查资料吧,一张图看一下就明白了. 另一种比较小的P ...

  10. 数据结构与算法(Python)

    数据结构与算法(Python) Why? 我们举一个可能不太恰当的例子: 如果将最终写好运行的程序比作战场,我们码农便是指挥作战的将军,而我们所写的代码便是士兵和武器. 那么数据结构和算法是什么?答曰 ...