【CodeForces】914 E. Palindromes in a Tree 点分治
【题意】给定一棵树,每个点都有一个a~t的字符,一条路径回文定义为路径上的字符存在一个排列构成回文串,求经过每个点的回文路径数。n<=2*10^5。
【算法】点分治
【题解】状压20位的二进制表示一条路径的字符状态,点分治过程中维护扫描过的路径只须维护状态桶数组,t[i]表示前面状态为i的路径条数。
合并:考虑当前状态为j,要使合并的状态满足条件即i^j=1<<k(0<=k<20)或i^j=0,移项得i=j^(1<<k)或i=j,所以路径数是Σ t [ j^(1<<k) ]+t[j]。
统计每个点:对于当前要处理的重心x,先遍历所有子树得到整个t[]数组,然后对每个子树先删除其在桶里的状态,然后扫一遍贡献子树中每个点,最后将子树的状态加回桶中。
这样可以做到每条路径都贡献到每个点,要特殊处理重心的贡献。
复杂度O(n log n)。
#include<cstdio>
#include<cctype>
#include<algorithm>
#define ll long long
using namespace std;
const int maxn=,maxN=;
int tot,first[maxn],sz[maxn],vis[maxn],sum,root,a[maxn],u,v,n;
ll ans[maxn],t[maxN];
struct edge{int v,from;}e[maxn*]; void insert(int u,int v){tot++;e[tot].v=v;e[tot].from=first[u];first[u]=tot;}
void getroot(int x,int fa){
sz[x]=;
bool ok=;
for(int i=first[x];i;i=e[i].from)if(e[i].v!=fa&&!vis[e[i].v]){
getroot(e[i].v,x);
sz[x]+=sz[e[i].v];
if(sz[e[i].v]>sum/)ok=;
}
if(ok&&sz[x]>=sum/)root=x;
}
void dfs(int x,int fa,int p,int s){
t[s^=(<<a[x])]+=p;
for(int i=first[x];i;i=e[i].from)if(e[i].v!=fa&&!vis[e[i].v])dfs(e[i].v,x,p,s);
}
ll calc(int x,int fa,int s){
s^=(<<a[x]);ll num=t[s];
for(int i=;i<;i++)num+=t[s^(<<i)];
for(int i=first[x];i;i=e[i].from)if(e[i].v!=fa&&!vis[e[i].v])num+=calc(e[i].v,x,s);
ans[x]+=num;
return num;
}
void solve(int x,int s){
vis[x]=;
dfs(x,,,);
ll num=t[];
for(int i=;i<;i++)num+=t[<<i];
for(int i=first[x];i;i=e[i].from)if(!vis[e[i].v]){
dfs(e[i].v,x,-,<<a[x]);
num+=calc(e[i].v,x,);
dfs(e[i].v,x,,<<a[x]);
}
ans[x]+=num/;
dfs(x,,-,);
for(int i=first[x];i;i=e[i].from)if(!vis[e[i].v]){
if(sz[e[i].v]>sz[x])sum=s-sz[x];else sum=sz[e[i].v];
getroot(e[i].v,x);
solve(root,sum);
}
}
char s[maxn];
int main(){
scanf("%d",&n);
for(int i=;i<n;i++){
scanf("%d%d",&u,&v);
insert(u,v);insert(v,u);
}
scanf("%s",s+);
for(int i=;i<=n;i++)a[i]=s[i]-'a';
sum=n;
getroot(,);
solve(root,sum);
for(int i=;i<=n;i++)printf("%lld ",ans[i]+);
return ;
}
【CodeForces】914 E. Palindromes in a Tree 点分治的更多相关文章
- Codeforces 1039D You Are Given a Tree [根号分治,整体二分,贪心]
洛谷 Codeforces 根号分治真是妙啊. 思路 考虑对于单独的一个\(k\)如何计算答案. 与"赛道修建"非常相似,但那题要求边,这题要求点,所以更加简单. 在每一个点贪心地 ...
- CF914E Palindromes in a Tree(点分治)
link 题目大意:给定一个n个点的树,每个点都有一个字符(a-t,20个字符) 我们称一个路径是神犇的,当这个路径上所有点的字母的某个排列是回文 求出对于每个点,求出经过他的神犇路径的数量 题解: ...
- codeforces 1065F Up and Down the Tree
题目链接:codeforces 1065F Up and Down the Tree 题意:给出一棵树的节点数\(n\)以及一次移动的最大距离\(k\),现在有一个标记在根节点1处,每一次可以进行一下 ...
- Codeforces 914H Ember and Storm's Tree Game 【DP】*
Codeforces 914H Ember and Storm's Tree Game 题目链接 ORZ佬 果然出了一套自闭题 这题让你算出第一个人有必胜策略的方案数 然后我们就发现必胜的条件就是树上 ...
- Codeforces Round #499 (Div. 1) F. Tree
Codeforces Round #499 (Div. 1) F. Tree 题目链接 \(\rm CodeForces\):https://codeforces.com/contest/1010/p ...
- CodeForces 1251B --- Binary Palindromes
[CodeForces 1251B --- Binary Palindromes] Description A palindrome is a string t which reads the sam ...
- [Codeforces 553E]Kyoya and Train(期望DP+Floyd+分治FFT)
[Codeforces 553E]Kyoya and Train(期望DP+Floyd+分治FFT) 题面 给出一个\(n\)个点\(m\)条边的有向图(可能有环),走每条边需要支付一个价格\(c_i ...
- codeforces 914E Palindromes in a Tree(点分治)
You are given a tree (a connected acyclic undirected graph) of n vertices. Vertices are numbered fro ...
- Palindromes in a Tree CodeForces - 914E
https://vjudge.net/problem/CodeForces-914E 点分就没一道不卡常的? 卡常记录: 1.把不知道为什么设的(unordered_map)s换成了(int[])s ...
随机推荐
- 【BioCode】读文件夹以发现缺失文件
代码说明: 使用单个蛋白质的txt计算PSSM生成的结果为单个的PSSM文件. 但是由于一些原因(如蛋白质序列过长),会导致一些蛋白质txt文件无法计算出pssm,为了找到这些没有计算出pssm的蛋白 ...
- PHP关于传众多参数还是传上下文对象的性能测试
在开发微信公众平台平台的过程中,有这么几个参数总是需要传来传去,$userOpenId,$message,$time. 在整个程序的运行过程中,为了函数方便的处理,将这三个变量一直放在参数列表里.关于 ...
- MVC 中创建自己的异常处理
1.新建类一个类继承 HandleErrorAttribute 类把异常书写到队列中 public class MyExceptionAttribute: HandleErrorAttribute { ...
- POJ2374_Fence Obstacle Course
题意是描述是这样的,给你n个围栏,对于每个围栏你必须走到其边上才可以往下跳,现在问你从初始最高位置的n个围栏,到原点,水平走过的路程最少是多少? 其实我可可以这样来考虑问题.由于每次都是从板子的左右两 ...
- BZOJ 2152 聪聪可可(树形DP)
给出一颗n个点带边权的树(n<=20000),求随机选择两个点,使得它们之间的路径边权是3的倍数的概率是多少. 首先总的对数是n*n,那么只需要统计路径边权是3的倍数的点对数量就行了. 考虑将无 ...
- C++解析-外传篇(3):动态内存申请的结果
0.目录 1.动态内存申请一定成功吗? 2.new_handler() 函数 3.小结 1.动态内存申请一定成功吗? 问题: 动态内存申请一定成功吗? 常见的动态内存分配代码: C代码: C++代码: ...
- 洛谷 P3157 [CQOI2011]动态逆序对 解题报告
P3157 [CQOI2011]动态逆序对 题目描述 对于序列\(A\),它的逆序对数定义为满足\(i<j\),且\(A_i>A_j\)的数对\((i,j)\)的个数.给\(1\)到\(n ...
- Cisco Smart Install远程命令执行漏洞
0x01前言 在Smart Install Client代码中发现了基于堆栈的缓冲区溢出漏洞,该漏洞攻击者无需身份验证登录即可远程执行任意代码.cisco Smart Install是一种“即插即用” ...
- 第三周——构建一个简单的Linux系统MenuOS
[洪韶武 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ] 第三周 构建一个 ...
- 框架----Web框架本质
一.Web框架本质 众所周知,对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端. #!/usr/bin/env python #coding:ut ...