CF914E Palindromes in a Tree(点分治)
题面
题解
题意:给你一颗 n 个顶点的树(连通无环图)。顶点从 1 到 n 编号,并且每个顶点对应一个在‘a’到‘t’的字母。 树上的一条路径是回文是指至少有一个对应字母的排列为回文。 对于每个顶点,输出通过它的回文路径的数量。 注意:从u到v的路径与从v到u的路径视为相同,只计数一次
性质:回文字符串至多一个字母次数为奇数
因为字母只有'a'~'t'
那么可以状压一下
然后就是套点分治就好了
注意:顶点经过的次数要除以2(因为每条路径算了两次)
Code
#include<bits/stdc++.h>
#define LL long long
#define RG register
using namespace std;
const int N = 200010;
inline int gi() {
RG int x = 0; RG char c = getchar(); bool f = 0;
while (c != '-' && (c < '0' || c > '9')) c = getchar();
if (c == '-') c = getchar(), f = 1;
while (c >= '0' && c <= '9') x = x*10+c-'0', c = getchar();
return f ? -x : x;
}
struct node {
int to, next;
}g[N<<1];
int last[N], gl;
inline void add(int x, int y) {
g[++gl] = (node) {y, last[x]};
last[x] = gl;
return ;
}
int sum, f[N], siz[N], rt;
bool vis[N];
void getroot(int u, int fa) {
siz[u] = 1; f[u] = 0;
for (int i = last[u]; i; i = g[i].next) {
int v = g[i].to; if (v == fa || vis[v]) continue;
getroot(v, u);
f[u] = max(f[u], siz[v]);
siz[u] += siz[v];
}
f[u] = max(f[u], sum-siz[u]);
if (f[rt] > f[u]) rt = u;
return ;
}
char a[N];
int s[N], t[10050000];
void dfs(int x, int fa, int p, int S) {
t[S ^= (1 << s[x])] += p;
for (int i = last[x]; i; i = g[i].next) {
int v = g[i].to;
if (v == fa||vis[v]) continue;
dfs(v, x, p, S);
}
}
LL ans[N];
LL calc(int x, int fa, int S) {
S ^= (1 << s[x]);
LL cnt = t[S];//都为偶数个
for (int i = 0; i < 20; i++) cnt += t[S^(1<<i)];//出现了一个次数为奇数个
for (int i = last[x]; i; i = g[i].next) {
int v = g[i].to;
if (v == fa || vis[v]) continue;
cnt += calc(v, x, S);
}
ans[x] += cnt;
return cnt;
}
void solve(int x) {
vis[x] = 1;
dfs(x, 0, 1, 0);
LL cnt = t[0];
for (int i = 0; i < 20; i++) cnt += t[1<<i];
//单个一条链
for (int i = last[x]; i; i = g[i].next) {
int v = g[i].to; if (vis[v]) continue;
dfs(v, x, -1, 1<<s[x]);//去掉以v开头的链
cnt += calc(v, x, 0); //计算组合起来的路径
dfs(v, x, 1, 1<<s[x]);
}
dfs(x, 0, -1, 0);
ans[x] += cnt/2;//算了两次啦
for (int i = last[x]; i; i = g[i].next) {
int v = g[i].to; if(vis[v]) continue;
sum = siz[v];rt = 0;
getroot(v, 0);
solve(rt);
}
return ;
}
int main() {
//freopen(".in", "r", stdin);
//freopen(".out", "w", stdout);
int n = gi();
for (int i = 1; i < n; i++) {
int u = gi(), v = gi();
add(u, v); add(v, u);
}
scanf("%s", a);
for (int i = 0; i < n; i++) s[i+1] = a[i]-'a';
f[0] = sum = n; rt = 0;
getroot(1, 0); solve(rt);
for (int i = 1; i <= n; i++)
printf("%lld ", ans[i]+1);
return 0;
}
CF914E Palindromes in a Tree(点分治)的更多相关文章
- CF914E Palindromes in a Tree(点分治)
link 题目大意:给定一个n个点的树,每个点都有一个字符(a-t,20个字符) 我们称一个路径是神犇的,当这个路径上所有点的字母的某个排列是回文 求出对于每个点,求出经过他的神犇路径的数量 题解: ...
- 【CodeForces】914 E. Palindromes in a Tree 点分治
[题目]E. Palindromes in a Tree [题意]给定一棵树,每个点都有一个a~t的字符,一条路径回文定义为路径上的字符存在一个排列构成回文串,求经过每个点的回文路径数.n<=2 ...
- CF914E Palindromes in a Tree
$ \color{#0066ff}{ 题目描述 }$ 给你一颗 n 个顶点的树(连通无环图).顶点从 1 到 n 编号,并且每个顶点对应一个在'a'到't'的字母. 树上的一条路径是回文是指至少有一个 ...
- codeforces 914E Palindromes in a Tree(点分治)
You are given a tree (a connected acyclic undirected graph) of n vertices. Vertices are numbered fro ...
- 【BZOJ-1468】Tree 树分治
1468: Tree Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1025 Solved: 534[Submit][Status][Discuss] ...
- HDU 4812 D Tree 树分治+逆元处理
D Tree Problem Description There is a skyscraping tree standing on the playground of Nanjing Unive ...
- POJ 1741 Tree 树分治
Tree Description Give a tree with n vertices,each edge has a length(positive integer less than 1 ...
- [bzoj 1468][poj 1741]Tree [点分治]
Description Give a tree with n vertices,each edge has a length(positive integer less than 1001). Def ...
- 【CF434E】Furukawa Nagisa's Tree 点分治
[CF434E]Furukawa Nagisa's Tree 题意:一棵n个点的树,点有点权.定义$G(a,b)$表示:我们将树上从a走到b经过的点都拿出来,设这些点的点权分别为$z_0,z_1... ...
随机推荐
- SSH隧道技术简介
本文的受众如果你遇到了以下问题,那么你应该阅读这篇文章 我听说过这种技术,我对它很感兴趣 我想在家里访问我在公司的机器(写程序,查数据,下电影). 公司为了防止我们用XX软件封锁了它的端口或者服务器地 ...
- AntD02 Table组件的使用
1 前提准备 1.1 创建一个angular项目 1.2 将 Ant Design 整合到 Angular 项目中 1.3 官方文档 点击前往 2 简单使用 <nz-table #rowSele ...
- 171. Excel Sheet Column Number Excel表格的字母转成数字
[抄题]: Given a column title as appear in an Excel sheet, return its corresponding column number. For ...
- 无返回值的函数如何捕获出错情况(检查errno常量)
在执行这个函数前,先清除errno,函数返回时,检查errno常量. 每次程序调用失败的时候,系统会自动用用错误代码填充errno这个全局变量,这样你只需要读errno这个全局变量就可以获得失败原因了 ...
- 显著水平alpha
http://blog.minitab.com/blog/adventures-in-statistics-2/understanding-hypothesis-tests:-significance ...
- 235D Graph Game
传送门 题目大意 https://www.luogu.org/problemnew/show/CF235D 分析 我们先考虑它是树的情况 我们设$event(x,y)$表示删除点x是y与x联通这件事对 ...
- 利用osmosis导出osm城市数据
转载(未测试) 方法核心就是利用osmosis的导出指定功能,即是从大范围导出小范围的基本用例. 我们只需要知道我们所需要提取的城市的经纬度范围, 例如广州市的经纬度范围是北纬22.26~23.56度 ...
- C# 用代码返回上一页
若我们在后台.cs文件中想做到让浏览器返回上一页,我们可以在.cs代码中这样写 Page.ClientScript.RegisterStartupScript(Page.GetType(), &quo ...
- Python中常用模块二
一.hashlib (加密) hashlib:提供摘要算法的模块 1.正常的md5算法 import hashlib # 提供摘要算法的模块 md5 = hashlib.md5() md5.upd ...
- 认识Filter
1). Filter 是什么 ? ①. JavaWEB 的一个重要组件, 可以对发送到 Servlet 的请求进行拦截, 并对响应也进行拦截. ②. Filter 是实现了 Filter 接口的 Ja ...