[SDOI2016] 模式字符串 (BZOJ4598 & VIJOS1995)
首先直接点分+hash就可以做,每个点用hash判断是否为S重复若干次后的前缀或后缀,每个子树与之前的结果O(m)暴力合并。在子树大小<m时停止分治,则总复杂度为O(nlog(n/m))。
问题在于n<=1e6。据说有O(n)的DP做法?写点分的话需要一大波常数优化……据说SDOI现场写了这题的全卡常T了……注意BZOJ并没有大数据,如果常数够小的话可以去VIJOS提交。
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long u64;
typedef u64 ll;
const int N=1e6+5;
struct edge{int v;edge*s;}e[N*2];
edge*l1=e,*h[N];
void ins(int u,int v){
edge s={v,h[u]};
*(h[u]=l1++)=s;
}
int q,n,m,s1,s2,s3,d=1,siz[N],f1[N],f2[N],f3[N],f4[N];
bool vis[N];
char t1[N],t2[N];
ll c1[N],c2[N];
u64 ans;
void dfs1(int u,int v){
int s4=0;
s3=max(s3,d++);
siz[u]=1;
for(edge*i=h[u];i;i=i->s)
if(i->v!=v&&!vis[i->v]){
dfs1(i->v,u);
siz[u]+=siz[i->v];
s4=max(s4,siz[i->v]);
}
if(max(s4,s1-siz[u])*2<=s1)
s2=u;
--d;
}
void dfs3(int u,int v,ll w){
++d,w=w*223+t1[u];
if(w==c1[d])++f1[d%m];
if(w==c2[d])++f2[d%m];
for(edge*i=h[u];i;i=i->s)
if(i->v!=v&&!vis[i->v])
dfs3(i->v,u,w);
--d;
}
void dfs2(int u){
s3=0,dfs1(u,0),u=s2;
if(s3*2-1<m)return;
for(int j=0;j<m;++j)
f3[j]=f4[j]=0;
f3[1]=f4[1]=1;
for(edge*i=h[u];i;i=i->s)
if(!vis[i->v]){
for(int j=0;j<m;++j)
f1[j]=f2[j]=0;
dfs3(i->v,u,t1[u]);
for(int j=0;j<m;++j)
ans+=(u64)f1[j]*f4[(m-j+1)%m]+(u64)f2[j]*f3[(m-j+1)%m];
for(int j=0;j<m;++j)
f3[j]+=f1[j],f4[j]+=f2[j];
}
vis[u]=1;
int s5=s1;
for(edge*i=h[u];i;i=i->s)
if(!vis[i->v]){
s1=siz[i->v]<siz[u]?siz[i->v]:s5-siz[u];
if(s1>=m)dfs2(i->v);
}
}
struct buf{
char z[1<<25],*s;
buf():s(z){
z[fread(z,1,sizeof z,stdin)]=0;
}
void pre(char*v){
while(*s<48)++s;
while(*s>32)*v++=*s++;
*v=0;
}
operator int(){
int x=0;
while(*s<48)++s;
while(*s>32)
x=x*10+*s++-48;
return x;
}
}it;
int main(){
q=it;
while(q--){
n=it,m=it,it.pre(t1+1);
for(int i=1;i<=n;++i)
h[i]=0,vis[i]=0;
l1=e;
for(int i=2;i<=n;++i){
int u=it,v=it;
ins(u,v),ins(v,u);
}
it.pre(t2+1);
ll w=1;
int i=1;
int j=m;
for(int k=1;k<=n;++k){
c1[k]=c1[k-1]+w*t2[i];
c2[k]=c2[k-1]+w*t2[j];
w*=223;
if(++i>m)i=1;
if(--j<1)j=m;
}
ans=0,s1=n,dfs2(1);
printf("%llu\n",ans);
}
}
[SDOI2016] 模式字符串 (BZOJ4598 & VIJOS1995)的更多相关文章
- 【BZOJ4598】[Sdoi2016]模式字符串 树分治+hash
[BZOJ4598][Sdoi2016]模式字符串 Description 给出n个结点的树结构T,其中每一个结点上有一个字符,这里我们所说的字符只考虑大写字母A到Z,再给出长度为m的模式串s,其中每 ...
- P4075 [SDOI2016]模式字符串
总结 P4075 [SDOI2016]模式字符串 题目描述 给出n个结点的树结构T,其中每一个结点上有一个字符,这里我们所说的字符只考虑大写字母A到Z,再给出长度为m的模式串s,其中每一位仍然是A到z ...
- bzoj4598: [Sdoi2016]模式字符串
Description 给出n个结点的树结构T,其中每一个结点上有一个字符,这里我们所说的字符只考虑大写字母A到Z,再给出长度为m 的模式串s,其中每一位仍然是A到z的大写字母.Alice希望知道,有 ...
- BZOJ4598 [Sdoi2016]模式字符串 【点分治 + hash】
题目 给出n个结点的树结构T,其中每一个结点上有一个字符,这里我们所说的字符只考虑大写字母A到Z,再给出长度为m 的模式串s,其中每一位仍然是A到z的大写字母.Alice希望知道,有多少对结点< ...
- Bzoj4598: [Sdoi2016]模式字符串 点分治 哈希
国际惯例的题面:这种关于树上路径的题,我也没什么好办法,只好点分治.考虑当前分治重心为root,如何统计经过分治重心的路径的答案.我们令prf[i]表示某个点到root的路径(不含root)已经循环匹 ...
- BZOJ4598: [Sdoi2016]模式字符串(点分治 hash)
题意 题目链接 Sol 直接考虑点分治+hash匹配 设\(up[i]\)表示\(dep \% M = i\)的从下往上恰好与前\(i\)位匹配的个数 \(down\)表示\(dep \% M = i ...
- bzoj 4598: [Sdoi2016]模式字符串
题目描述 给出n个结点的树结构T,其中每一个结点上有一个字符,这里我们所说的字符只考虑大写字母A到Z,再给出长度为m的模式串s,其中每一位仍然是A到z的大写字母. Alice希望知道,有多少对结点&l ...
- [SDOI2016]模式字符串
Description 给出n个结点的树结构T,其中每一个结点上有一个字符,这里我们所说的字符只考虑大写字母A到Z,再给出长度为m的模式串s,其中每一位仍然是A到z的大写字母.Alice希望知道,有多 ...
- BZOJ.4598.[SDOI2016]模式字符串(点分治 Hash)
LOJ BZOJ 洛谷 点分治.考虑如何计算过\(rt\)的答案. 记\(pre[i]\)表示(之前的)子树内循环匹配了\(S\)的前缀\(i\)的路径有多少,\(suf[i]\)表示(之前的)子树内 ...
随机推荐
- Lighttpd 服务器的安装
https://www.cnblogs.com/rongfengliang/articles/3503228.html
- Educational Codeforces Round 51 (Rated for Div. 2) The Shortest Statement
题目链接:The Shortest Statement 今天又在群里看到一个同学问$n$个$n$条边,怎么查询两点直接最短路.看来这种题还挺常见的. 为什么最终答案要从42个点的最短路(到$x,y$) ...
- Ubuntu 16.04安装微信
微信没有出Linux的版本,但是可以通过以下方式解决: 1.使用网页版,除了没有公众号之后,一切都没问题,包括传文件等. 网页登录地址:https://wx.qq.com/ 2.使用第三方版本,只不过 ...
- android 图片的平移,缩放和旋转
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools= ...
- BUPT 2012复试机考 4T
题目描述 我们都学习过计算机网络,知道网络层IP协议数据包的头部格式如下: 其中IHL表示IP头的长度,单位是4字节:总长表示整个数据包的长度,单位是1字节.传输层的TCP协议数据段的头部格式如下: ...
- js跳出循环的方法区别( break, continue, return ) 及 $.each 的(return true 和 return false)
js编程语法之break语句: break语句会使运行的程序立刻退出包含在最内层的循环或者退出一个switch语句. 由于它是用来退出循环或者switch语句,所以只有当它出现在这些语句时,这种形式的 ...
- a#x#i#o#s封装
封装的js文件如下: /* 用于修改 axios 的一些公用配置,具体参看文档 */import axios from 'axios'import store from '@/store/index. ...
- androidproject有红色叹号的解决方式
首先,查看SDK版本号,一般有两处.第一处是project.properties文件里的target=android-?改动成自己工程相应的SDK版本号.第二处是manifest文件里, androi ...
- Animated progress view with CAGradientLayer(带翻译)
Animated progress view with CAGradientLayer(带翻译) Modern software design is getting flatter and thin ...
- 翻译:A Tutorial on the Device Tree (Zynq) -- Part IV
获取资源信息 内核模块驱动加载之后,就开始把硬件资源管理起来,如读写寄存器.接收中断. 来看看设备树里的一条: xillybus_0: xillybus@50000000 { compatible = ...