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;
}

loj2065 「SDOI2016」模式字符串的更多相关文章

  1. 题解 loj2065 「SDOI2016」模式字符串

    点分治. 考虑经过当前分治中心\(u\)的点对数量. 这种数点对数的问题,有一个套路.我们可以依次考虑\(u\)的每个儿子,看用当前的儿子,能和之前已经考虑过的所有儿子,组成多少点对.这样所有合法的点 ...

  2. 【LOJ】#2065. 「SDOI2016」模式字符串

    题解 按秩合并怎么清数组对我来说真是世纪性难题 我们很熟练地想到点分,如果我们认为某个点到重心是正着读的,由于它的深度固定,它的串也是固定的,我们只要预处理出所有长度正着重复的串,反着重复的串,和它们 ...

  3. liberOJ #2033. 「SDOI2016」生成魔咒 后缀数组

    #2033. 「SDOI2016」生成魔咒     题目描述 魔咒串由许多魔咒字符组成,魔咒字符可以用数字表示.例如可以将魔咒字符 1 11.2 22 拼凑起来形成一个魔咒串 [1,2] [1, 2] ...

  4. 「SDOI2016」储能表(数位dp)

    「SDOI2016」储能表(数位dp) 神仙数位 \(dp\) 系列 可能我做题做得少 \(QAQ\) \(f[i][0/1][0/1][0/1]\) 表示第 \(i\) 位 \(n\) 是否到达上界 ...

  5. [LOJ 2070] 「SDOI2016」平凡的骰子

    [LOJ 2070] 「SDOI2016」平凡的骰子 [题目链接] 链接 [题解] 原题求的是球面面积 可以理解为首先求多面体重心,然后算球面多边形的面积 求重心需要将多面体进行四面体剖分,从而计算出 ...

  6. 「SDOI2016」数字配对

    「SDOI2016」数字配对 题目大意 传送门 题解 \(a_i\) 是 \(a_j\) 的倍数,且 \(\frac{a_i}{a_j}\) 是一个质数,则将 \(a_i,a_j\) 质因数分解后,其 ...

  7. 「SDOI2016」征途 题解

    「SDOI2016」征途 先浅浅复制一个方差 显然dp,可以搞一个 \(dp[i][j]\)为前i段路程j天到达的最小方差 开始暴力转移 \(dp[i][j]=min(dp[k][j-1]+?)(j- ...

  8. loj2424 「NOIP2015」子串[字符串DP]

    给定字符串 A,B,要求从 A 中取出互不重叠的 k 个非空子串,按照出现顺序拼起来后等于 B.求方案数.n ≤ 1000,m ≤ 200. 主要是状态的转移.先设计出$f_{i,j,k}$表长度$B ...

  9. 【LOJ】#2070. 「SDOI2016」平凡的骰子

    题解 用了一堆迷之复杂的结论结果迷之好写的计算几何???? 好吧,要写立体几何了 如果有名词不懂自己搜吧 首先我们求重心,我们可以求带权重心,也就是x坐标的话是所有分割的小四面体的x坐标 * 四面体体 ...

随机推荐

  1. uLua学习之数据交互(三)

    前言 在上节中,大概谈了一下如何在lua脚本中调用unity3d中的方法来创建游戏物体,这只是很小的一个方面,uLua的优势在于对unity3d中C#语言的扩展和定制.那么如何扩展和定制呢?其中的数据 ...

  2. windows 右键崩溃 解决方法

    [问题描述] 选中一个文件,右键之后无法弹出菜单,最后显示: 资源管理器未响应. [参考方法] https://www.jianshu.com/p/d627c941467a [方法介绍] 1.下载Sh ...

  3. Python自学之路——自定义简单装饰器

    看了微信公众号推送的一道面试题,发现了闭包的问题,学习时间短,从来没有遇到过这种问题,研究一下. Python函数作用域 global:全局作用域 local:函数内部作用域 enclosing:函数 ...

  4. json字符串转换成对象需要注意的问题

    json转换成对象的时候应该尽量避免出现特殊的符号,如“\”这样的字符在转义成数组的时候会被去除掉,最好的例子就是后台返回的内容为存储路径的JSON,这时候最好是把一个斜杠变为两个斜杠,如: [{&q ...

  5. Android(java)学习笔记152:采用get请求提交数据到服务器(qq登录案例)

    1.GET请求:    组拼url的路径,把提交的数据拼装url的后面,提交给服务器. 缺点:(1)安全性(Android下提交数据组拼隐藏在代码中,不存在安全问题)  (2)长度有限不能超过4K(h ...

  6. 【洛谷3275】[SCOI2011] 糖果(差分约束系统入门题)

    点此看题面 大致题意: 有\(N\)个小朋友,要求每个人都得到糖果,且每个人的糖果总数满足一定的关系式,请你求出至少共分给小朋友们多少糖果. 关系式的转换 首先,我们可以将题目中给定的式子进行转换: ...

  7. NOIP2018赛前停课集训记——最后的刷板子计划

    前言 再过两天就\(NOIP2018\)了. 于是,我决定不做其他题目,开始一心一意刷板子了. 这篇博客记录的就是我的刷板子计划. [洛谷3383][模板]线性筛素数 这种普及-的题目我还写挂了两次( ...

  8. 【转载】2018 hosts 持续更新访问 gu歌【更新于:2018-05-03】

      修改HOSTS实现免费,简单访问谷歌的目的   也是比较稳定的方法.修改hosts.修改hosts的方法,原理在于直接存储谷歌网站的IP地址.这样就不用DNS来解析网址了.也就是说,当我们输入谷歌 ...

  9. 为什么L1稀疏,L2平滑?

    使用机器学习方法解决实际问题时,我们通常要用L1或L2范数做正则化(regularization),从而限制权值大小,减少过拟合风险.特别是在使用梯度下降来做目标函数优化时,很常见的说法是,  L1正 ...

  10. js表单序列化时,非空判断

    在项目中,对于数据的传输一般需要非空的判断,而数据字段较多时一般直接将表单序列化,此时如何判断非空,如下 因为将表单序列化时,数据格式为 trainKind=1&trainKindCode=1 ...