AC自动机模板
来源:互联网 发布:网络销售法律法规 编辑:程序博客网 时间:2024/05/29 16:17
#include <cstdio>#include <algorithm>#include <cmath>#include <queue>#include <algorithm>#define N 500006using namespace std;char st[1000005];char keyword[55];int n,m;int next[N][26],cnt[N],fail[N],pos;//初始化字典树的节点int newNode ( ){ for ( int i = 0; i < 26 ; i++ ) next[pos][i] = 0; fail[pos] = cnt[pos] = 0; return pos++;}//构建字典树void insert ( char *s ){ int i,p = 0;//p当前为根节点,i为字符串初始位置 for ( i = 0 ; s[i] ; i++ ) { //获得这一字母的节点,如果不存在,创建新的 int k = s[i] -'a' , &x = next[p][k]; p = x?x : x = newnode(); } cnt[p]++; // 位运算要用}//通过宽搜构建失败指针void makeNext ( ){ int i; queue<int> q; q.push(0); // 将根节点放入队列中 while ( !q.empty() ) { int u = q.front(); //统计匹配到当前位置能够匹配到的串的个数 cnt[u] += cnt[fail[u]]; q.pop (); for ( int i = 0 ; i < 26 ; i++ ) { int v = next[u][i]; //如果v是0,证明不能匹配,所以通过fail指针找到深度小于当前深度但 //是深度最大的与v和自身的最近公共祖先相邻的与v具有相同字母的节点 //需要通过fail指针跳转过去 if ( v == 0 ) next[u][i] = next[fail[u]][i]; else q.push (v); //否则,要将v推到队列中去,用于宽搜 if ( u && v ) fail[v] = next[fail[u]][i]; } }}int query ( char *s ){ int ret = 0, idx , d = 0; for ( int i = 0; s[i]; i++ ) { idx = s[i] -'a'; d = next[d][idx]; //将当前位置作为串的结尾能匹配到的串的个数 ret += cnt[d]; //将串的个数清0,避免重复统计 cnt[d] = 0; } return ret;}
0 0
- 【AC自动机】AC自动机模板
- AC自动机模板
- AC自动机模板
- AC自动机模板
- AC自动机模板
- AC自动机模板
- AC自动机模板
- AC自动机模板 hdu2222
- AC自动机模板
- AC自动机模板
- 数据结构--AC自动机--模板
- ac自动机模板
- AC自动机模板
- AC自动机模板
- hdu2222 ac自动机模板
- ac自动机模板。。。。。
- AC自动机模板 LA4670
- AC自动机模板
- java.lang.NumberFormatException
- 彩色图像--色彩空间 总结
- 使用 resizableImageWithCapInsets获得想要的图片
- linux学习笔记--基本命令的学习--压缩与解压缩命令
- leetcode-21 Merge Two Sorted Lists
- AC自动机模板
- ARP地址解析协议与RAPR逆地址解析协议
- 转载----android应用程序中获取view的位置
- Visual Studio 2005/2008中如何编译和运行C++程序
- vim+cscope+ctags打造属于自己的IDE
- 关于算法练习1.1中的中参数传递方式思考
- 如何用堆栈实现后序遍历的非递归程序
- Sizeof与Strlen的区别与联系
- uint8_t / uint16_t / uint32_t /uint64_t 是什么数据类型 - 大总结,看完全明白了