题目描述

题解

我们可以先对trie树建出广义SAM,然后维护一下right集合大小(注意right集合在广义SAM上的维护方式)。

然后把匹配穿往广义SAM上匹配,假设现在匹配到了x节点,那么x的所有祖先后可以被匹配上,那么一个节点的贡献即为r[x]*(l[x]-l[fa[x]])

维护这玩意的和就好了,最下面的节点特判一下。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#define N 1600002
#define M 8000002
using namespace std;
typedef long long ll;
char c[],s[M];
int cnt,n,father,pa[N],len,tong[N],rnk[N];
ll sum[N],ans;
int l[N],ch[N][],fa[N],r[N];
inline int rd(){
int x=;char c=getchar();bool f=;
while(!isdigit(c)){if(c=='-')f=;c=getchar();}
while(isdigit(c)){x=(x<<)+(x<<)+(c^);c=getchar();}
return f?-x:x;
}
inline int ins(int last,int x){
int p=last;
if(ch[p][x]){
int q=ch[p][x];
if(l[p]+==l[q]){r[q]++;return q;}
else{
int nq=++cnt;l[nq]=l[p]+;r[nq]=;//care!!!!!!!!!!!!!!!
memcpy(ch[nq],ch[q],sizeof(ch[q]));
fa[nq]=fa[q];fa[q]=nq;
for(;ch[p][x]==q;p=fa[p])ch[p][x]=nq;
return nq;
}
}
else{
int np=++cnt;l[np]=l[p]+;r[np]=;
for(;p&&!ch[p][x];p=fa[p])ch[p][x]=np;
if(!p)fa[np]=;
else{
int q=ch[p][x];
if(l[p]+==l[q])fa[np]=q;
else{
int nq=++cnt;l[nq]=l[p]+;
memcpy(ch[nq],ch[q],sizeof(ch[q]));
fa[nq]=fa[q];fa[q]=fa[np]=nq;
for(;ch[p][x]==q;p=fa[p])ch[p][x]=nq;
}
}
return np;
}
}
int main(){
n=rd();cnt=;pa[]=;
for(int i=;i<=n;++i){
father=rd();scanf("%s",c);
pa[i]=ins(pa[father],c[]-'a');
}
scanf("%s",s+);len=strlen(s+);
for(int i=;i<=cnt;++i)tong[l[i]]++;
for(int i=;i<=n;++i)tong[i]+=tong[i-];
for(int i=;i<=cnt;++i)rnk[tong[l[i]]--]=i;
for(int i=cnt;i>=;--i){int x=rnk[i];r[fa[x]]+=r[x];}
r[]=;
for(int i=;i<=cnt;++i){int x=rnk[i];sum[x]=sum[fa[x]]+1ll*(l[x]-l[fa[x]])*r[x];}
int now=,le=;
for(int i=;i<=len;++i){
if(ch[now][s[i]-'a'])le++,now=ch[now][s[i]-'a'];
else{
for(;now&&!ch[now][s[i]-'a'];now=fa[now]);
if(now)le=l[now]+,now=ch[now][s[i]-'a'];
else le=,now=;
}
if(now!=)ans+=sum[fa[now]]+1ll*(le-l[fa[now]])*r[now];
}
cout<<ans;
return ;
}
#include<iostream>
#include<cstdio>
#include<cstring>
#define N 1600002
#define M 8000002
using namespace std;
typedef long long ll;
char c[],s[M];
int cnt,n,father,pa[N],len,tong[N],rnk[N];
ll sum[N],ans;
int l[N],ch[N][],fa[N],r[N];
inline int rd(){
int x=;char c=getchar();bool f=;
while(!isdigit(c)){if(c=='-')f=;c=getchar();}
while(isdigit(c)){x=(x<<)+(x<<)+(c^);c=getchar();}
return f?-x:x;
}
inline int ins(int last,int x){
int p=last;
if(ch[p][x]){
int q=ch[p][x];
if(l[p]+==l[q]){r[q]++;return q;}
else{
int nq=++cnt;l[nq]=l[p]+;r[nq]=;//care!!!!!!!!!!!!!!!
memcpy(ch[nq],ch[q],sizeof(ch[q]));
fa[nq]=fa[q];fa[q]=nq;
for(;ch[p][x]==q;p=fa[p])ch[p][x]=nq;
return nq;
}
}
else{
int np=++cnt;l[np]=l[p]+;r[np]=;
for(;p&&!ch[p][x];p=fa[p])ch[p][x]=np;
if(!p)fa[np]=;
else{
int q=ch[p][x];
if(l[p]+==l[q])fa[np]=q;
else{
int nq=++cnt;l[nq]=l[p]+;
memcpy(ch[nq],ch[q],sizeof(ch[q]));
fa[nq]=fa[q];fa[q]=fa[np]=nq;
for(;ch[p][x]==q;p=fa[p])ch[p][x]=nq;
}
}
return np;
}
}
int main(){
n=rd();cnt=;pa[]=;
for(int i=;i<=n;++i){
father=rd();scanf("%s",c);
pa[i]=ins(pa[father],c[]-'a');
}
scanf("%s",s+);len=strlen(s+);
for(int i=;i<=cnt;++i)tong[l[i]]++;
for(int i=;i<=n;++i)tong[i]+=tong[i-];
for(int i=;i<=cnt;++i)rnk[tong[l[i]]--]=i;
for(int i=cnt;i>=;--i){int x=rnk[i];r[fa[x]]+=r[x];}
r[]=;
for(int i=;i<=cnt;++i){int x=rnk[i];sum[x]=sum[fa[x]]+1ll*(l[x]-l[fa[x]])*r[x];}
int now=,le=;
for(int i=;i<=len;++i){
if(ch[now][s[i]-'a'])le++,now=ch[now][s[i]-'a'];
else{
for(;now&&!ch[now][s[i]-'a'];now=fa[now]);
if(now)le=l[now]+,now=ch[now][s[i]-'a'];
else le=,now=;
}
if(now!=)ans+=sum[fa[now]]+1ll*(le-l[fa[now]])*r[now];
}
cout<<ans;
return ;
}

bzoj3756pty的字符串(后缀自动机+计数)的更多相关文章

  1. 模板—字符串—后缀自动机(后缀自动机+线段树合并求right集合)

    模板—字符串—后缀自动机(后缀自动机+线段树合并求right集合) Code: #include <bits/stdc++.h> using namespace std; #define ...

  2. [TJOI2019]甲苯先生和大中锋的字符串——后缀自动机+差分

    题目链接: [TJOI2019]甲苯先生和大中锋的字符串 对原串建后缀自动机并维护$parent$树上每个点的子树大小,显然子树大小为$k$的节点所代表的子串出现过$k$次,那么我们需要将$[len[ ...

  3. Wannafly Camp 2020 Day 2D 卡拉巴什的字符串 - 后缀自动机

    动态维护任意两个后缀的lcp集合的mex,支持在串末尾追加字符. Solution 考虑在 SAM 上求两个后缀的 LCP 的过程,无非就是找它们在 fail 树上的 LCA,那么 LCP 长度就是这 ...

  4. Tjoi2019 甲苯先生和大中锋的字符串 后缀自动机_差分

    tjoi胆子好大,直接出了两道送分题...... 都 9102 年了,还有省选出模板题QAQ...... Code: #include <bits/stdc++.h> #define se ...

  5. 字符串数据结构模板/题单(后缀数组,后缀自动机,LCP,后缀平衡树,回文自动机)

    模板 后缀数组 #include<bits/stdc++.h> #define R register int using namespace std; const int N=1e6+9; ...

  6. HDU 4622 Reincarnation (查询一段字符串的不同子串个数,后缀自动机)

    Reincarnation Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)To ...

  7. 字符串(后缀自动机):Codeforces Round #129 (Div. 1) E.Little Elephant and Strings

    E. Little Elephant and Strings time limit per test 3 seconds memory limit per test 256 megabytes inp ...

  8. BZOJ 3473: 字符串 [广义后缀自动机]

    3473: 字符串 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 354  Solved: 160[Submit][Status][Discuss] ...

  9. [十二省联考2019]字符串问题——后缀自动机+parent树优化建图+拓扑序DP+倍增

    题目链接: [十二省联考2019]字符串问题 首先考虑最暴力的做法就是对于每个$B$串存一下它是哪些$A$串的前缀,然后按每组支配关系连边,做一遍拓扑序DP即可. 但即使忽略判断前缀的时间,光是连边的 ...

随机推荐

  1. 配置SQLServer,允许远程连接

    需要别人远程你的数据库,首先需要的是在一个局域网内,或者连接的是同一个路由器,接下来就是具体步骤: (一)首先是要检查SQLServer数据库服务器中是否允许远程链接.其具体操作为: (1)打开数据库 ...

  2. Oracle 不小心删除undo数据文件以及磁盘空间不足导致不能登录的解决办法

    在一次测试中,由于导入的数据量过大导致事务一直提交失败因为磁盘空间不够用了,一检查发现是undo表空间不够用,于是重新创建了一个表空间,准备把之前的undo表空间删除,删除时却发现一直删不掉,因为它一 ...

  3. CentOS7安装Jenkins自动化部署maven项目

    前言: 最近要弄一个jenkins工具,已经安装好了并且jenkins使用部署项目的流程已经基本走通,上图: 话不多说,开始 第一步:安装jenkins: [ 准备环境: 在centOS7环境上:安装 ...

  4. C# Note23: 如何自定义类型使用foreach循环

    前言 在foreach语句代码中,我们经常是对List,Collection,Dictionary等类型的数据进行操作,不过C#允许用户自定义自己的类型来使用foreach语句.那么自定义类型能够使用 ...

  5. vue.js实战——vue 实时时间

    created:实例创建完成后调用,此阶段完成了数据的观测等,但尚未挂载,$el还不可用,需要初始化处理一些数据时会比较有用. mounted:el挂载到实例上后调用,一般我们的第一个业务逻辑会在这里 ...

  6. Flutter之 LimitedBox、Offstage、OverflowBox、SizedBox详解

    1. LimitedBox A box that limits its size only when it's unconstrained. 1.1 简介 LimitedBox,通过字面意思,也可以猜 ...

  7. zabbix-2.4.5的安装配置与使用

    系统最小化安装 环境: zabbix_server     12.1.1.1 zabbix_agent     12.1.1.2 zabbix_proxy      12.1.1.3 1.安装环境: ...

  8. c++中结构体sort()排序

    //添加函数头 #include <algorithm> //定义结构体Yoy typedef struct { double totalprice;         //总价 doubl ...

  9. Git简介及安装

    1 Git简介 Git是一个开源的分布式版本控制系统,可以有效.高速的处理从很小到非常大的项目版本管理. Git是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码 ...

  10. javadoc格式化,解决多个形参空格暴多,页面溢出问题

    格式化前: 格式化后: pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xml ...