HDU 3695 (AC自动机)
来源:互联网 发布:纱裙布料淘宝 编辑:程序博客网 时间:2024/04/30 06:25
题目链接:点击这里
题意:求文本串中出现的模式串个数。模式串反着出现也算。
把模式串正反都扔进自动机,节点开一个vector存下来所有的以这个节点结尾的模式串,然后扫一遍就行了。注意正反算一种
trick:q不是只有一位
#include <cstdio>#include <cmath>#include <algorithm>#include <iostream>#include <vector>#include <queue>#include <cstring>using namespace std;#define maxn 500005#define maxm 5100005int n;struct trie { int next[maxn][26], fail[maxn]; vector <int> end[maxn]; bool vis[maxn]; int root, cnt; int new_node () { memset (next[cnt], -1, sizeof next[cnt]); end[cnt++].clear (); return cnt-1; } void init () { memset (vis, 0, sizeof vis); cnt = 0; root = new_node (); } void insert (char *buf, int pos) {//字典树插入一个单词 int len = strlen (buf); int now = root; for (int i = 0; i < len; i++) { int id = buf[i]-'A'; if (next[now][id] == -1) { next[now][id] = new_node (); } now = next[now][id]; } end[now].push_back (pos); } void build () {//构建fail指针 queue <int> q; fail[root] = root; for (int i = 0; i < 26; i++) { if (next[root][i] == -1) { next[root][i] = root; } else { fail[next[root][i]] = root; q.push (next[root][i]); } } while (!q.empty ()) { int now = q.front (); q.pop (); for (int i = 0; i < 26; i++) { if (next[now][i] == -1) { next[now][i] = next[fail[now]][i]; } else { fail[next[now][i]] = next[fail[now]][i]; q.push (next[now][i]); } } } } int query (char *buf) { int len = strlen (buf); int now = root; int res = 0; for (int i = 0; i < len; i++) { int id = buf[i]-'A'; now = next[now][id]; int tmp = now; while (tmp != root) { int Max = end[tmp].size (); if (Max) { for (int j = 0; j < Max; j++) { vis[end[tmp][j]] = 1; } end[tmp].clear (); } else break; tmp = fail[tmp];//沿着失配边走 } } for (int i = 0; i < n; i++) if (vis[i] || vis[i+n]) res++; return res; }}ac;char a[maxm], b[maxm];void deal () { int len = 0; int n = strlen (a); for (int i = 0; i < n; i++) { if (a[i] != '[') { b[len++] = a[i]; continue; } i++; int num = 0; while (a[i] <= '9' && a[i] >= '0') { num = num*10+a[i]-'0'; i++; } for (int j = 0; j < num; j++) b[len++] = a[i]; i++; } b[len] = 0;}int main () { int t; scanf ("%d", &t); while (t--) { scanf ("%d", &n); ac.init (); for (int i = 0; i < n; i++) { scanf ("%s", a); ac.insert (a, i); int len = strlen (a); for (int j = 0; j < len/2; j++) { swap (a[j], a[len-j-1]); } ac.insert (a, i+n); } ac.build (); scanf ("%s", a); deal (); printf ("%d\n", ac.query (b)); } return 0;}
0 0
- HDU-3695-ac自动机
- hdu 3695 ac自动机
- hdu 3695 ac自动机
- HDU 3695 (AC自动机)
- HDU 3695 AC自动机 裸题
- hdu 3695 AC自动机模板题
- AC自动机 hdu 2222
- HDU 2222(AC 自动机)
- hdu 2222 AC自动机
- hdu 3065(AC自动机)
- HDU 2222 AC自动机
- HDU 2896 AC自动机
- HDU 3065 AC自动机
- HDU 2896 AC自动机
- Hdu 2222 [AC自动机]
- hdu 2222 AC自动机 。。
- hdu 2896 ac自动机
- hdu 2222 AC自动机
- Spider Man(cf705B)(水题乱搞)
- 【总结】RAM-Like芯片地址线为什么不是从0开始
- IntelliJ IDEA 12.0搭建Maven Web SSH2架构项目示例(二)
- String、StringBuffer和StringBuilder类比较
- Unity3D学习成潮流:如何成为一位Unity3D开发者
- HDU 3695 (AC自动机)
- 如何用set命令设置Windows 7操作系统的环境变量
- 希尔排序
- 给UIImageView设置一组图片动画,每张图片停留时间不一祥
- opengl顶点着色器
- 列出mysql所有数据库表的存储引擎
- Fragment
- 设计模式:解释器
- Android--JNI的开发流程