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.

Input

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.

Output

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.

Examples
input

Copy
5
1 2
2 3
3 4
3 5
abcbb
output

Copy
1 3 4 3 3 
input

Copy
7
6 2
4 3
3 7
5 2
7 2
1 4
afefdfs
output
1 4 1 1 2 4 2 
Note

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(点分治)的更多相关文章

  1. 【CodeForces】914 E. Palindromes in a Tree 点分治

    [题目]E. Palindromes in a Tree [题意]给定一棵树,每个点都有一个a~t的字符,一条路径回文定义为路径上的字符存在一个排列构成回文串,求经过每个点的回文路径数.n<=2 ...

  2. CF914E Palindromes in a Tree(点分治)

    link 题目大意:给定一个n个点的树,每个点都有一个字符(a-t,20个字符) 我们称一个路径是神犇的,当这个路径上所有点的字母的某个排列是回文 求出对于每个点,求出经过他的神犇路径的数量 题解: ...

  3. 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 题意 给出一棵树,每条边上有一个字符,字符集大小只 ...

  4. codeforces 812E Sagheer and Apple Tree(思维、nim博弈)

    codeforces 812E Sagheer and Apple Tree 题意 一棵带点权有根树,保证所有叶子节点到根的距离同奇偶. 每次可以选择一个点,把它的点权删除x,它的某个儿子的点权增加x ...

  5. codeforces 220 C. Game on Tree

    题目链接 codeforces 220 C. Game on Tree 题解 对于 1节点一定要选的 发现对于每个节点,被覆盖切选中其节点的概率为祖先个数分之一,也就是深度分之一 代码 #includ ...

  6. Codeforces E. Alyona and a tree(二分树上差分)

    题目描述: Alyona and a tree time limit per test 2 seconds memory limit per test 256 megabytes input stan ...

  7. Palindromes in a Tree CodeForces - 914E

    https://vjudge.net/problem/CodeForces-914E 点分就没一道不卡常的? 卡常记录: 1.把不知道为什么设的(unordered_map)s换成了(int[])s ...

  8. Codeforces 1039D You Are Given a Tree [根号分治,整体二分,贪心]

    洛谷 Codeforces 根号分治真是妙啊. 思路 考虑对于单独的一个\(k\)如何计算答案. 与"赛道修建"非常相似,但那题要求边,这题要求点,所以更加简单. 在每一个点贪心地 ...

  9. Codeforces 434E - Furukawa Nagisa's Tree(三元环+点分治)

    Codeforces 题面传送门 & 洛谷题面传送门 场号 hopping,刚好是我的学号(指 round 的编号) 注:下文中分别用 \(X,Y,K\) 代替题目中的 \(x,y,k\) 注 ...

随机推荐

  1. @RestController的方法中 路径参数带.(点号)配置

    如下面这种//http://localhost:8080/api/v1/user/info/email/test@163.com @RequestMapping(value = "/info ...

  2. vector array and normal stanard array

    array 数组的长度固定 vector 自由存储区(栈),动态长度 普通标准数组相对较不安全,不方便; array,vector对象成员函数支持数组越界检测,同时代价是效率问题: array,普通标 ...

  3. Memcached的过期数据的过期机制及删除机制(LRU)

    Memcached的过期数据的过期机制及删除机制1.当某个值过期后,并没有从内存删除,因此,使用stats命令统计时,curr_item参数有信息(不为0)2.当某个新值去占用他的位置时,当成空chu ...

  4. HTTP断点续传下载的原理

    frombegintoend原文HTTP断点续传下载的原理 要实现断点续传下载文件,首先要了解断点续传的原理.断点续传其实就是在上一次下载断开的位置开始继续下载,HTTP协议中,可以在请求报文头中加入 ...

  5. shiro和Spring整合使用注解时没有执行realm的doGetAuthorizationInfo回调方法的解决(XML配置)

    在使用Shiro框架进行项目整合时,使用注解在使用Shiro框架进行项目整合时,使用注解在使用Shiro框架进行项目整合时,使用注解@RequiresPermissions为方法提供是需要的权限,但是 ...

  6. unity在安卓中横屏闪退

    竖屏没问题,横屏闪退 配置文件的AndoridManifest.xml横竖屏设置要和UNITY设置的一致,否则就会强退 UNITY横竖屏设置

  7. 使用zTree展开节点后,覆盖了下一个节点

    如图所示,结果是zTree与<fieldset>标签不兼容....我去!!! 也就是说Ztree不能放在<fieldset>标签中..

  8. shell if,case,for,while语法

    #shell if的语法 if [空格 xxx 空格] then echo xxxxx exit 1/2/3/4/.... 0表示正确. elif [空格 xxx 空格] then echo xxxx ...

  9. Crack IDEA

    使用破解补丁 Crack IDEA→在http://idea.lanyus.com/上可以找到最新的破解补丁,下载并放到软件的bin目录下 →更改bin目录下的两个文件:Idea.exe.vmopti ...

  10. MYSQL中GROUP BY的细节及SELECT语句顺序

    一.GROUP BY语句的细节 我们知道,在sql中,GROUP BY语句主要用来给数据分组,以便能对每个组进行聚集计算,但是GROUP BY也有一些限制需要知道: 1. GROUP BY字句可以包含 ...