传送门:https://www.luogu.org/problem/P3808

题解:是一个AC自动机的裸题了,注释加在代码里面了

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 5, sigma_size = 26;
int ch[maxn][sigma_size];
int tot; //结点总数
int ans = 0;
int f[maxn]; //失配函数
int last[maxn];//表示 i沿着失配指针往回走时,遇到的下一个单词结点(即是该单词的最后一个结点)的编号
int val[maxn]; //若值不为0表示该结点是单词的最后一个结点
char a[maxn];
char b[maxn];
void init()
{
tot = 1;
memset(val, 0, sizeof(val));
memset(ch, 0, sizeof(ch));
memset(f, 0, sizeof(f));
memset(last, 0, sizeof(last));
}
void insert(char *str)//将所有模式串构建成一个字典树
{
int p = 0;
int len = strlen(str);
for(int i = 0; i < len; i++)
{
int c = str[i] - 'a';
if(!ch[p][c])
{
ch[p][c] = tot++;
}
p = ch[p][c];
}
val[p] ++;//标记此结点为末尾 同时代表模式串中 相同的字符串有几个
}
void find(char *str)
{
int n = strlen(str);
int u = 0;
for(int i = 0; i < n; i++)
{
int s = str[i] - 'a';
while(u && !ch[u][s])
u = f[u];
u = ch[u][s];
if(val[u])
{
ans += val[u];
val[u] = 0;
}
else if(val[last[u]])//判断是否为单词的末尾结点
{
ans += val[last[u]];
val[last[u]] = 0;
}
}
}
void getfail()//通过BFS进行计算fail函数
{
queue<int> q;
f[0] = 0;
for(int c = 0; c < sigma_size; c++)
{
int u = ch[0][c];
if(u)//将所有根结点的孩子结点全部压入队列
{
f[u] = 0;//根结点的孩子结点失配只能跳到根结点
q.push(u);
last[u] = 0;
}
}
while(!q.empty())
{
int r = q.front();
q.pop();
for(int c = 0; c < sigma_size; c++)
{
int u = ch[r][c];
if(!u)
continue;//{ch[r][c]=ch[f[r]][c];continue}(则可以把while语句删除),路径压缩
q.push(u);
int v = f[r];
while(v && !ch[v][c])//沿着失配边走 直到可以匹配 和KMP类似
v = f[v];
f[u] = ch[v][c];
last[u] = val[f[u]] ? f[u] : last[f[u]];//last需要指向单词末尾 用val数组判断
}
}
}
int main(void)
{
int n;
scanf("%d", &n);
init();
for(int i = 1; i <= n; i++)
{
scanf("%s", a);
insert(a);//根据情况而定 还可以改为insert(a,value) ;表示该单词的权重
}
getfail();
scanf("%s", b);
find(b);
cout << ans << endl;
return 0;
}

最新文章

  1. JavaScript创建对象
  2. mysql分组合并GROUP_CONCAT
  3. Ubuntu 新建swap分区及启用
  4. Android 【问题汇总】列表数组越界的问题
  5. Web安全--使用Salt + Hash将密码加密后再存储进数据库
  6. JAVA获取CLASSPATH路径--转
  7. SQL语句一之建库
  8. 9个最新的手机/移动设备jQuery插件
  9. oracle 11gR2默认密码修改
  10. OpenGL ES着色器语言之操作数(官方文档第五章)
  11. Git 生成 SSH 公钥
  12. Android 音视频编解码——YUV视频格式详解
  13. leetcode:程序员面试技巧
  14. Python必备库
  15. web前端bug积累
  16. PEP8 规范
  17. ROADS POJ - 1724(分层最短路)
  18. 利用angularjs完成注册表单
  19. python 函数参数 *a **kw
  20. How to calculate elapsed / execute time in Java

热门文章

  1. js原型链理解(3)--构造借用继承
  2. c++ opencv 数学函数示例
  3. JS - 局部方法改变全局变量的值
  4. DNS bind9安装
  5. 自定义checkbox,redio等
  6. hdu3359 Kind of a Blur
  7. 67.ORM查询条件:range的使用,使用make_aware将navie time 转换为aware time
  8. APP分享视频H5页面
  9. BMP位图图像格式简介
  10. MBR&amp;/BOOT&amp;GRUB