codeforces 914E Palindromes in a Tree(点分治)
You are given a tree (a connected acyclic undirected graph) of n vertices. Vertices are numbered from 1 to n and each vertex is assigned a character from a to t.
A path in the tree is said to be palindromic if at least one permutation of the labels in the path is a palindrome.
For each vertex, output the number of palindromic paths passing through it.
Note: The path from vertex u to vertex v is considered to be the same as the path from vertex v to vertex u, and this path will be counted only once for each of the vertices it passes through.
The first line contains an integer n (2 ≤ n ≤ 2·105) — the number of vertices in the tree.
The next n - 1 lines each contain two integers u and v (1 ≤ u, v ≤ n, u ≠ v) denoting an edge connecting vertex u and vertex v. It is guaranteed that the given graph is a tree.
The next line contains a string consisting of n lowercase characters from a to t where the i-th (1 ≤ i ≤ n) character is the label of vertex i in the tree.
Print n integers in a single line, the i-th of which is the number of palindromic paths passing through vertex i in the tree.
5
1 2
2 3
3 4
3 5
abcbb
1 3 4 3 3
7
6 2
4 3
3 7
5 2
7 2
1 4
afefdfs
1 4 1 1 2 4 2
In the first sample case, the following paths are palindromic:
2 - 3 - 4
2 - 3 - 5
4 - 3 - 5
Additionally, all paths containing only one vertex are palindromic. Listed below are a few paths in the first sample that are not palindromic:
1 - 2 - 3
1 - 2 - 3 - 4
1 - 2 - 3 - 5
题意:给你一颗 n 个顶点的树(连通无环图)。顶点从 1 到 n 编号,并且每个顶点对应一个在‘a’到‘t’的字母。 树上的一条路径是回文是指至少有一个对应字母的排列为回文。 对于每个顶点,输出通过它的回文路径的数量。 注意:从u到v的路径与从v到u的路径视为相同,只计数一次。
题解:
首先是一个结论
本题要求路径的某个排列为回文串,很显然,路径上最多有一个字母出现奇数次。只需要记录奇偶性显然可以用状压去解决。
根据这个结论,我们可以推出对于一个点u,他到某个点v的路径如果满足条件,显然状压的数字等于0或者1<<i(i<=19),这个时候可以考虑搞出一个中点k,于是问题等价于dis(u,k)^dis(v,k)等于0或者1<<i(i<=19)
这显然是点分治的思路
考虑点分治中的暴力怎么写:首先对于重心进行dfs,求出所有点到重心的dis,dis表示路径上个字母的奇偶性,并且记录 dis_idisi 的数量。
接着对于每棵子树将该子树对所有dis的数量贡献全部去掉,再对该子树进行dfs,对于每个点的dis,统计与他异或等于0或者1<<i(i<=19)的数量,即为该点贡献答案,值得注意的是,经过该点的路径一定经过其父节点,因为是从另一颗子树中跑过来的,所以在dfs返回的时候应该给父节点加上子节点的贡献。接着把该子树的dis全部加回去跑下一棵子树。
因为每个点本身都是一个回文串,所以最后答案要加一。
代码如下:
#include<map>
#include<set>
#include<queue>
#include<cmath>
#include<cstdio>
#include<string>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#define poi void
#define int long long
using namespace std; vector<int> g[];
char c[];
int n,ans[],a[],size[],vis[],f[],tmp[(<<)|]; poi get_size(int now,int fa)
{
size[now]=;
f[now]=fa;
for(int i=;i<g[now].size();i++)
{
if(vis[g[now][i]]||g[now][i]==fa) continue;
get_size(g[now][i],now);
size[now]+=size[g[now][i]];
}
} int get_zx(int now,int fa)
{
if(size[now]==) return now;
int son,maxson=-;
for(int i=;i<g[now].size();i++)
{
if(vis[g[now][i]]||g[now][i]==fa) continue;
if(maxson<size[g[now][i]])
{
maxson=size[g[now][i]];
son=g[now][i];
}
}
int zx=get_zx(son,now);
while(size[zx]<*(size[now]-size[zx])) zx=f[zx];
return zx;
} poi get(int now,int fa,int sta,int kd)
{
sta^=(<<a[now]);
tmp[sta]+=kd;
for(int i=;i<g[now].size();i++)
{
if(vis[g[now][i]]||g[now][i]==fa) continue;
get(g[now][i],now,sta,kd);
}
} int calc(int now,int fa,int sta)
{
sta^=(<<a[now]);
int num=tmp[sta];
for(int i=;i<=;i++)
{
num+=tmp[sta^(<<i)];
}
for(int i=;i<g[now].size();i++)
{
if(vis[g[now][i]]||g[now][i]==fa) continue;
num+=calc(g[now][i],now,sta);
}
ans[now]+=num;
return num;
} poi solve(int now)
{
vis[now]=;
get(now,,,);
long long num=tmp[];
for(int i=;i<=;i++)
{
num+=tmp[<<i];
}
for(int i=;i<g[now].size();i++)
{
if(vis[g[now][i]]) continue;
get(g[now][i],,<<a[now],-);
num+=calc(g[now][i],,);
get(g[now][i],,<<a[now],);
}
ans[now]+=num/;
get(now,,,-);
for(int i=;i<g[now].size();i++)
{
if(vis[g[now][i]]) continue;
get_size(g[now][i],);
int zx=get_zx(g[now][i],);
solve(zx);
}
} signed main()
{
scanf("%lld",&n);
for(int i=;i<n;i++)
{
int from,to;
scanf("%lld%lld",&from,&to);
g[from].push_back(to);
g[to].push_back(from);
}
scanf("%s",c+);
for(int i=;i<=n;i++)
{
a[i]=c[i]-'a';
}
solve();
for(int i=;i<=n;i++)
{
printf("%lld ",ans[i]+);
}
}
codeforces 914E Palindromes in a Tree(点分治)的更多相关文章
- 【CodeForces】914 E. Palindromes in a Tree 点分治
[题目]E. Palindromes in a Tree [题意]给定一棵树,每个点都有一个a~t的字符,一条路径回文定义为路径上的字符存在一个排列构成回文串,求经过每个点的回文路径数.n<=2 ...
- CF914E Palindromes in a Tree(点分治)
link 题目大意:给定一个n个点的树,每个点都有一个字符(a-t,20个字符) 我们称一个路径是神犇的,当这个路径上所有点的字母的某个排列是回文 求出对于每个点,求出经过他的神犇路径的数量 题解: ...
- codeforces 741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths(启发式合并)
codeforces 741D Arpa's letter-marked tree and Mehrdad's Dokhtar-kosh paths 题意 给出一棵树,每条边上有一个字符,字符集大小只 ...
- codeforces 812E Sagheer and Apple Tree(思维、nim博弈)
codeforces 812E Sagheer and Apple Tree 题意 一棵带点权有根树,保证所有叶子节点到根的距离同奇偶. 每次可以选择一个点,把它的点权删除x,它的某个儿子的点权增加x ...
- codeforces 220 C. Game on Tree
题目链接 codeforces 220 C. Game on Tree 题解 对于 1节点一定要选的 发现对于每个节点,被覆盖切选中其节点的概率为祖先个数分之一,也就是深度分之一 代码 #includ ...
- Codeforces E. Alyona and a tree(二分树上差分)
题目描述: Alyona and a tree time limit per test 2 seconds memory limit per test 256 megabytes input stan ...
- Palindromes in a Tree CodeForces - 914E
https://vjudge.net/problem/CodeForces-914E 点分就没一道不卡常的? 卡常记录: 1.把不知道为什么设的(unordered_map)s换成了(int[])s ...
- Codeforces 1039D You Are Given a Tree [根号分治,整体二分,贪心]
洛谷 Codeforces 根号分治真是妙啊. 思路 考虑对于单独的一个\(k\)如何计算答案. 与"赛道修建"非常相似,但那题要求边,这题要求点,所以更加简单. 在每一个点贪心地 ...
- Codeforces 434E - Furukawa Nagisa's Tree(三元环+点分治)
Codeforces 题面传送门 & 洛谷题面传送门 场号 hopping,刚好是我的学号(指 round 的编号) 注:下文中分别用 \(X,Y,K\) 代替题目中的 \(x,y,k\) 注 ...
随机推荐
- Julia - 短路求值
&& 和 || 的布尔运算符被称为短路求值 它们连接一系列布尔表达式,仅计算最少的表达式来确定整个链的布尔值 在表达式 a && b 中,只有 a 为 true 时才计 ...
- thymeleaf switch在表格中的使用,遇到的空行问题
switch在表格中的使用时 如果把<td>写在<div th:switch="${data.isShow}"> 里面导致外面出现很多空的<div&g ...
- Python Twisted系列教程21: Twisted和Haskell
作者:dave@http://krondo.com/twisted-and-haskell/ 译者: Cheng Luo 你可以从”第一部分 Twist理论基础“开始阅读:也可以从”Twisted ...
- Monkey测试工具介绍
---------------------------------------------------------------------------------------------------- ...
- leetcode859
class Solution { public: bool buddyStrings(string A, string B) { if (A.length() != B.length()) { ret ...
- 什么是事件代理?DOM2.0标准事件模型的三个阶段
体验更优排版请移步原文:http://blog.kwin.wang/programming/js-event-delegation.html 事件代理,又称事件委托(Delegation),就是将处理 ...
- 一个简单的环境光shader
关于shader的一个简短的历史 在DirectX8之前,GPU有一个固定的方法去变换顶点和像素,称为“固定管线”.这使得在将它们传递给GPU后,开发者不可能操作顶点和像素的变换. DirectX8介 ...
- idea使用jrebel热部署插件
首先通过idea下载JReble插件 访问http://idea.lanyus.com/网站 跟着弹出框的步骤走就可以实现了: 在idea中使用tomcat部署项目 不要使用war:使用下面的文件
- js里面的三种注释方法
javascript(js)语言里面的注释方法有三种. 第一种是多行注释"/**/",一般js文件开头,介绍作者,函数等信息. /* *author:xxx *day:2008-0 ...
- beego 自定义模板函数
beego支持的模板函数不是很多,有时候前端展现数据的时候,要对数据进行格式化,所以要用到自定义模板函数 比如我的前端模板上有时间和模板大小这2个数据,原始数据都是int的时间戳和byte单位的数据, ...