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\) 注 ...
随机推荐
- Ubuntu Server 16.04.1系统安装
一.Ubuntu Server 16.04.1系统安装 Ubuntu分为桌面版(desktop)和服务器版(Server),下面为大家介绍服务器版本Ubuntu Server 16.04.1的详细安装 ...
- 第二章:Android Studio概述(一)[学习Android Studio汉化教程]
Android Studio是一个视窗化的开发环境.为了充分利用有限的屏幕空间,不让你束手束脚,Android Studio 在特定的时间仅仅显示一小部分可用窗口. 除了一些上下文敏感的窗口和上下文 ...
- 03_java之基本语法
01创建引用类型变量公式 * A: 创建引用类型变量公式 * a: 我们要学的Scanner类是属于引用数据类型,我们先了解下引用数据类型. * b: 引用数据类型的定义格式 * 与定义基本数据类型变 ...
- OpenLayers 3 之 地图控件(control)
OpenLayers 3 之 地图控件(control) 地图控件(control)是指地图上比例尺,缩略图,拉近拉远的按钮,滚动控制条等控件,默认控件有三个,可以禁用. OpenLayers 3 之 ...
- fatal error C1010: 在查找预编译头时遇到意外的文件结尾 (转)
错误描述:fatal error C1010: 在查找预编译头时遇到意外的文件结尾.是否忘记了向源中添加“#include "stdafx.h"”? 错误分析: 此错误发生 ...
- IDEA2017 破解方式
1. 到网站 http://idea.lanyus.com/ 获取注册码. 2.填入下面的license server: http://intellij.mandroid.cn/ http://ide ...
- Delphi三层开发小技巧:TClientDataSet的Delta妙用
Delphi三层开发小技巧:TClientDataSet的Delta妙用 转载 2014年10月13日 09:41:14 标签: 三层 / ClientDataSet 318 from :http:/ ...
- Elasticsearch学习系列之term和match查询实例
Elasticsearch查询模式 一种是像传递URL参数一样去传递查询语句,被称为简单查询 GET /library/books/_search //查询index为library,type为boo ...
- curl 访问 k8s
curl https://mhc:6443/api --cacert ssl/ca.crt --key client_ssl/cs_client.key --cert client_ssl/cs_cl ...
- Linux实战教学笔记45:NoSQL数据库之redis持久化存储(一)
第1章 redis存储系统 1.1 redis概述 REmote DIctionary Server(Redis)是一个基于key-value键值对的持久化数据库存储系统.redis和大名鼎鼎的Mem ...