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. Activiti20180624

    1.工作流介绍 工作流(WorkFlow),是对工作流程及其各操作步骤之间业务规则的抽象.概括.描述.工作建模,即将工作流程中的工作如何前后组织在一起的逻辑和规则,在计算机中以恰当的模型进行表示并对其 ...

  2. org.hibernate.HibernateException: Unable to get the defa

    今天整合SSH框架时出现了这个问题,以前一直没注意,在网上找了一下解决方案,找到了问题的解决方法,特记录如下: 1.原因:在中,javax.persistence.validation.mode默认情 ...

  3. Aizu 0121 Seven Puzzle(变进制数的完美hash)

    一遍预处理跑完所有情况,O(1)回答就好.状态记录我用的康拓和逆康拓. #include<bits/stdc++.h> using namespace std; ]; ]; ]; int ...

  4. POJ-1936 All in All---字符串水题

    题目链接: https://vjudge.net/problem/POJ-1936 题目大意: 给两个字符串,判断是s1是不是s2的子序列 思路: 水 #include<iostream> ...

  5. 【BZOJ2141】排队

    点此看题面 大致题意: 给你一个序列,每次交换两个数,求每次操作后的逆序对个数. 关于另一道题目 推荐先去看一下这道题目:[洛谷3759][TJOI2017] 不勤劳的图书管理员(貌似是此题的升级版) ...

  6. 20.JSON

    JSON是javascript的一个子集,利用js中的一些儿模式来表示结构化数据.不是只有javascript才使用JSON,JSON是一种数据格式,很多编程语言都有针对JSON的解析器和序列化器. ...

  7. CUDA并行存储模型

    CUDA将CPU作为主机(Host),GPU作为设备(Device).一个系统中可以有一个主机和多个设备.CPU负责逻辑性强的事务处理和串行计算,GPU专注于执行高度线程化的并行处理任务.它们拥有相互 ...

  8. Linux环境下使用xampp配置php开发环境

    XAMPP (Apache+MySQL+PHP+PERL)是一个功能强大的建站集成软件包.这个软件包原来的名字是LAMPP,但是为 了避免误 解,最新的几个版本就改名为 XAMPP 了.它可以在Win ...

  9. Scanner和 Random类,控制语句的例题,商品管理(直接赋值)

    Scanner类的使用: import java.util.Scanner; class Demo02 { public static void main(String[] args) { //1.导 ...

  10. checkbox 最多选两项

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...