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\) 注 ...
随机推荐
- Python+Selenium爬虫实战一《将QQ今日话题发布到个人博客》
前提条件: 1.使用Wamp Server部署WordPress个人博客,网上资料较多,这里不过多介绍 思路: 1.首先qq.com首页获取到今日话题的的链接: 2.通过今日话题链接访问到今日话题,并 ...
- HALCON形状匹配(转)
LIntExport Herror create_shape_model( const Hobject& Template , //reduce_domain后的模板图像 Hlong N ...
- mongodb(四)
Count+Distinct+Group数据库命令操作固定集合特性GridFS文件系统补充服务器端脚本 db.runCommand({group:{ ns:"persons", k ...
- 「小程序JAVA实战」小程序注册与后端联调(35)
转自:https://idig8.com/2018/09/01/xiaochengxujavashizhanxiaochengxuzhuceyuhouduanliandiao35/ 小程序的后端spr ...
- CentOS Grub、BASH 故障、解决方法
简介: Grub 常见的两种故障:Grub.conf 文件丢失.MBR 损坏 ( 不管恢复怎么样,还是先备份好吧 ) 一.Grub.conf 文件丢失 shell > rm -rf /boot/ ...
- mybatis mysql 批量insert 返回主键
Mybatis在插入单条数据的时候有两种方式返回自增主键: mybatis3.3.1支持批量插入后返回主键ID, 首先对于支持自增主键的数据库:useGenerateKeys和keyProper ...
- linux下mysql的源码安装
mysql有多中安装方法,本文只涉及编译安装,对其他方法感兴趣的可以自行百度. 1.首先获取mysql软件安装包,这里用wget下载 [root@localhost ~]# wget http://d ...
- iOS 布局之 Springs and Struts
“springs and struts” 模式,就是代码中的autosizing masks布局控制. autosizing mask决定了一个view会发生什么当它的superview 改变大小的时 ...
- #if (DEBUG)
//DEBUG必须大写,其它是不认的#if (DEBUG) Console.WriteLine("Debug");#else Conso ...
- 【POJ1811】Prime Test
[题目大意] 若n是素数,输出“Prime”,否则输出n的最小素因子,(n<=2^54) [题解] 和bzoj3667差不多,知识这道题没那么坑. 直接上Pollord_Rho和Rabin_Mi ...