ref不是太懂

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
typedef unsigned long long ull;
int T, n, m, hea[1000005], cnt, uu, vv, rnd[1000005], rot, siz[1000005];
int tot, sf[1000005], sg[1000005], ff[1000005], gg[1000005];
ull bse[1000005], hs1[1000005], hs2[1000005], ans;
char ss[1000005], tt[1000005];
bool vis[1000005];
struct Edge{
int too, nxt;
}edge[2000005];
void rn(int &x){
char ch=getchar();
x = 0;
while(ch<'0' || ch>'9') ch = getchar();
while(ch>='0' && ch<='9'){
x = x * 10 + ch - '0';
ch = getchar();
}
}
void add_edge(int fro, int too){
edge[++cnt].nxt = hea[fro];
edge[cnt].too = too;
hea[fro] = cnt;
}
void getRoot(int x, int f){
rnd[x] = 0;
siz[x] = 1;
for(int i=hea[x]; i; i=edge[i].nxt){
int t=edge[i].too;
if(!vis[t] && t!=f){
getRoot(t, x);
siz[x] += siz[t];
rnd[x] = max(rnd[x], siz[t]);
}
}
rnd[x] = max(rnd[x], tot-siz[x]);
if(rnd[x]<rnd[rot]) rot = x;
}
int dfs(int x, int f, int d, ull hx){
siz[x] = 1;
hx = hx * 131 + ss[x];
if(hs1[d]==hx){
ff[(d-1)%m+1]++;
ans += sg[m-(d-1)%m];
}
if(hs2[d]==hx){
gg[(d-1)%m+1]++;
ans += sf[m-(d-1)%m];
}
int tmp=1;
for(int i=hea[x]; i; i=edge[i].nxt){
int t=edge[i].too;
if(!vis[t] && t!=f){
siz[x] += siz[t];
tmp = max(tmp, dfs(t, x, d+1, hx)+1);
}
}
return tmp;
}
void work(int x){
vis[x] = true;
sf[1] = sg[1] = 1;
int tmp=0;
for(int i=hea[x]; i; i=edge[i].nxt){
int t=edge[i].too;
if(!vis[t]){
int k=min(m, dfs(t, x, 2, ss[x])+1);
tmp = max(tmp, k);
for(int j=1; j<=k; j++){
sf[j] += ff[j];
sg[j] += gg[j];
ff[j] = gg[j] = 0;
}
}
}
for(int i=1; i<=tmp; i++)
sf[i] = sg[i] = 0;
for(int i=hea[x]; i; i=edge[i].nxt){
int t=edge[i].too;
if(!vis[t]){
rot = 0;
tot = siz[t];
getRoot(t, x);
work(rot);
}
}
}
int main(){
cin>>T;
while(T--){
rn(n); rn(m);
scanf("%s", ss+1);
memset(hea, 0, sizeof(int)*(n+1));
memset(vis, 0, sizeof(bool)*(n+1));
cnt = ans = rot = 0;
tot = n;
for(int i=1; i<n; i++){
rn(uu); rn(vv);
add_edge(uu, vv);
add_edge(vv, uu);
}
scanf("%s", tt+1);
bse[0] = 1;
for(int i=1; i<=n; i++){
bse[i] = bse[i-1] * 131;
hs1[i] = hs1[i-1] + tt[(i-1)%m+1] * bse[i-1];
hs2[i] = hs2[i-1] + tt[m-(i-1)%m] * bse[i-1];
}
rnd[0] = 0x3f3f3f3f;
getRoot(1, 0);
work(rot);
printf("%llu\n", ans);
}
return 0;
}

最新文章

  1. dom 操作
  2. Web前端MVC框架
  3. 边框(border)边距(margin)和间隙(padding)属性的区别
  4. PHP性能优化简述
  5. php中静态变量和静态方法
  6. C++基础(1)
  7. python与unicode
  8. iOS中FMDB的使用【单例】
  9. C++ sizeof
  10. JBPM4.4GPD设计器中文乱码问题的另一种解决方法
  11. USB mass storage协议
  12. jQuery入门:认识jQuery
  13. 【Python3爬虫】百度一下,坑死你?
  14. Hadoop Partition函数应用(归档)
  15. 调试 .NET Framework 源代码、.DotNetCore源码
  16. json小知识
  17. [PHP] PHP数组的实现哈希表(HashTable)结构
  18. canvas抛物线运动demo
  19. python函数库及函数标准库
  20. Find the odd int

热门文章

  1. 提高jquery加载速率(有cdn就加载,没有就加载本地)
  2. 【迷你微信】基于MINA、Hibernate、Spring、Protobuf的即时聊天系统:8.自定义传输协议
  3. 五、c++实现离散傅里叶变换
  4. 这些年,在wp平台打拼的日子
  5. mongodb索引 全文索引之相似度查询
  6. ThreadLocal为什么要用WeakReference
  7. SqlServer2000事件探测器的使用
  8. Excel自动从身份证中提取生日、性别、年龄
  9. C#箴言之用属性来访问类的私有成员
  10. oc数组遍历