题目链接

洛谷:https://www.luogu.org/problemnew/show/P4075

LOJ:https://loj.ac/problem/2065

Solution

这种题看起来就很点分治啊...

我们可以发现,我们需要一个支持询问字符串相等,并且支持在一个串前面加一个串的数据结构,显然我们用哈希就行了。

那么我们直接开桶然后拿哈希维护,总复杂度\(O(Tn\log n)\)。

#include<bits/stdc++.h>
using namespace std; template<typename T> void read(T &x) {
x=0;T ff=1;char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-') ff=-ff;
for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=ff;
} void print(int x) {
if(x<0) putchar('-'),x=-x;
if(!x) return ;print(x/10),putchar(x%10+48);
}
void write(int x) {if(!x) putchar('0');else print(x);putchar('\n');} #define lf double
#define ll long long #define pii pair<int,int >
#define vec vector<int > #define pb push_back
#define mp make_pair
#define fr first
#define sc second #define FOR(i,l,r) for(int i=l,i##_r=r;i<=i##_r;i++) const int maxn = 1e6+10;
const int inf = 1e9;
const lf eps = 1e-8;
const int bs = 29;
const int mod = 1e6+3; ll ans;
char s[maxn];
int sz[maxn],rs[maxn],rp[maxn],rt,f[maxn],SZ,mxd,rrs[maxn],rrp[maxn];
int n,m,r[maxn],tag[maxn],head[maxn],tot,len,suf[maxn],pre[maxn],pw[maxn],vis[maxn];
struct edge{int to,nxt;}e[maxn<<1]; void add(int u,int v) {e[++tot]=(edge){v,head[u]},head[u]=tot;}
void ins(int u,int v) {add(u,v),add(v,u);} void prepare() {
for(len=m;len<n;len+=m)
for(int i=len+1;i<=len+m;i++) tag[i]=tag[i-len];
for(int i=1;i<=len;i++) pre[i]=(pre[i-1]*bs+tag[i])%mod;
suf[len+1]=0;for(int i=len;i;i--) suf[i]=(suf[i+1]*bs+tag[i])%mod;
reverse(suf+1,suf+len+1);
pw[0]=1;for(int i=1;i<=len;i++) pw[i]=pw[i-1]*bs%mod;
} void get_rt(int x,int fa) {
sz[x]=1,f[x]=0;
for(int i=head[x];i;i=e[i].nxt)
if(e[i].to!=fa&&!vis[e[i].to]) get_rt(e[i].to,x),sz[x]+=sz[e[i].to],f[x]=max(f[x],sz[e[i].to]);
f[x]=max(f[x],SZ-sz[x]);if(f[rt]>f[x]) rt=x;
} void calc(int x,int fa,int dep,int hs,const int &c) {
hs=(hs+1ll*r[x]*pw[dep])%mod;dep++;mxd=max(mxd,dep);
if(hs==pre[dep]) {
rrp[dep%m]++;
if(c==tag[dep%m+1]) ans+=rs[m-dep%m-1];
}
if(hs==suf[dep]) {
rrs[dep%m]++;
if(c==tag[m-dep%m]) ans+=rp[m-dep%m-1];
}
for(int i=head[x];i;i=e[i].nxt) if(e[i].to!=fa&&!vis[e[i].to]) calc(e[i].to,x,dep,hs,c);
} void dfs(int x) {
f[rt=0]=maxn;get_rt(x,0);x=rt;vis[x]=1;mxd=0;
rp[0]=rs[0]=1;int mmxd=0;
for(int i=head[x];i;i=e[i].nxt)
if(!vis[e[i].to]) {
mxd=0;calc(e[i].to,x,0,0,r[x]);mmxd=max(mmxd,mxd);
for(int j=0;j<=min(mxd,m);j++) rp[j]+=rrp[j],rs[j]+=rrs[j],rrp[j]=rrs[j]=0;
}
for(int i=0;i<=mmxd;i++) rs[i]=rp[i]=0;
for(int i=head[x];i;i=e[i].nxt)
if(!vis[e[i].to]) SZ=sz[e[i].to],dfs(e[i].to);
} void solve() {
read(n),read(m);scanf("%s",s+1);ans=0;
for(int i=1;i<=n;i++) r[i]=s[i]-'A'+1;
for(int x,y,i=1;i<n;i++) read(x),read(y),ins(x,y);
scanf("%s",s+1);
for(int i=1;i<=m;i++) tag[i]=s[i]-'A'+1;
prepare();SZ=n;dfs(1);write(ans);
} #define clr(x) memset(x,0,(n+3)*4) void clear() {clr(head),clr(vis);tot=0;} int main() {
int st=clock();
int t;read(t);while(t--) solve(),clear();
cerr << (double)(clock()-st)/1e3 << endl;
return 0;
}

[LOJ2065] [SDOI2016]模式字符串的更多相关文章

  1. 【BZOJ4598】[Sdoi2016]模式字符串 树分治+hash

    [BZOJ4598][Sdoi2016]模式字符串 Description 给出n个结点的树结构T,其中每一个结点上有一个字符,这里我们所说的字符只考虑大写字母A到Z,再给出长度为m的模式串s,其中每 ...

  2. P4075 [SDOI2016]模式字符串

    总结 P4075 [SDOI2016]模式字符串 题目描述 给出n个结点的树结构T,其中每一个结点上有一个字符,这里我们所说的字符只考虑大写字母A到Z,再给出长度为m的模式串s,其中每一位仍然是A到z ...

  3. bzoj4598: [Sdoi2016]模式字符串

    Description 给出n个结点的树结构T,其中每一个结点上有一个字符,这里我们所说的字符只考虑大写字母A到Z,再给出长度为m 的模式串s,其中每一位仍然是A到z的大写字母.Alice希望知道,有 ...

  4. bzoj 4598: [Sdoi2016]模式字符串

    题目描述 给出n个结点的树结构T,其中每一个结点上有一个字符,这里我们所说的字符只考虑大写字母A到Z,再给出长度为m的模式串s,其中每一位仍然是A到z的大写字母. Alice希望知道,有多少对结点&l ...

  5. BZOJ4598 [Sdoi2016]模式字符串 【点分治 + hash】

    题目 给出n个结点的树结构T,其中每一个结点上有一个字符,这里我们所说的字符只考虑大写字母A到Z,再给出长度为m 的模式串s,其中每一位仍然是A到z的大写字母.Alice希望知道,有多少对结点< ...

  6. [SDOI2016]模式字符串

    Description 给出n个结点的树结构T,其中每一个结点上有一个字符,这里我们所说的字符只考虑大写字母A到Z,再给出长度为m的模式串s,其中每一位仍然是A到z的大写字母.Alice希望知道,有多 ...

  7. BZOJ.4598.[SDOI2016]模式字符串(点分治 Hash)

    LOJ BZOJ 洛谷 点分治.考虑如何计算过\(rt\)的答案. 记\(pre[i]\)表示(之前的)子树内循环匹配了\(S\)的前缀\(i\)的路径有多少,\(suf[i]\)表示(之前的)子树内 ...

  8. Bzoj4598: [Sdoi2016]模式字符串 点分治 哈希

    国际惯例的题面:这种关于树上路径的题,我也没什么好办法,只好点分治.考虑当前分治重心为root,如何统计经过分治重心的路径的答案.我们令prf[i]表示某个点到root的路径(不含root)已经循环匹 ...

  9. BZOJ4598: [Sdoi2016]模式字符串(点分治 hash)

    题意 题目链接 Sol 直接考虑点分治+hash匹配 设\(up[i]\)表示\(dep \% M = i\)的从下往上恰好与前\(i\)位匹配的个数 \(down\)表示\(dep \% M = i ...

随机推荐

  1. 洛谷 P1432 倒水问题

    目录 题目 思路 \(Code\) 题目 戳 思路 \(bfs\) 第一遍提交\(50\),第二遍就\(100\)了,qwq \(Code\) #include<iostream> #in ...

  2. CSS — BEM 命名规范

    推荐阅读: https://juejin.im/post/5b925e616fb9a05cdd2ce70d 1 什么是 BEM 命名规范 Bem 是块(block).元素(element).修饰符(m ...

  3. OpenFOAM——90度T型管

    本算例来自<ANSYS Fluid Dynamics Verification Manual>中的VMFL010: Laminar Flow in a 90° Tee-Junction. ...

  4. 解决MySql ERROR 1698 (28000) 错误:Access denied for user 'root'@'localhost'

    今天尝试在Ubuntu虚拟机上安装MySql 数据库(版本是:5.7.23-0Ubuntu0.18.04.1),数据库安装很简单,就是三行命令:   sudo apt-get install mysq ...

  5. js注册表单中实现地区选择效果

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

  6. 如何使用git把本地代码上传(更新)到github上

    最近用到git和github记录一下 1.下载git并安装 到官网下载并安装就行了 *如果下载失败,或者太慢,可以复制链接到迅雷下载 2.上传 1.在github新建存储库 库名不能是中文 2.在需要 ...

  7. Service Function Chaining Resource Allocation: A Survey

    摘要: 服务功能链(SFC)是未来Internet的一项关键技术. 它旨在克服当前部署模型的僵化和静态限制. 该技术的应用依赖于可以将SFC最佳映射到衬底网络的算法. 这类算法称为"服务功能 ...

  8. windows服务器卸载补丁命令【转】

    一.可以试用cmd命令 wusa.exe /uninstall /kb: wusa.exe /uninstall /kb: wusa.exe /uninstall /kb:   二.使用DISM卸载补 ...

  9. 常见的SQL优化面试题

    1.在表中建立索引,优先考虑where.group by使用到的字段. 2.查询条件中,一定不要使用select *,因为会返回过多无用的字段会降低查询效率.应该使用具体的字段代替*,只返回使用到的字 ...

  10. 修改 commit 历史

    修改 commit 历史 参考:修改 git 历史提交 commit 信息(重写历史)git 修改已提交的内容 git init echo t.md>.gitignore git add .gi ...