HDU 2222 Keywords Search AC自动机
2016-01-26 16:33
323 查看
AC自动机 入门题
http://acm.hdu.edu.cn/showproblem.php?pid=2222/********************************************* Problem : HDU Author : NMfloat InkTime (c) NM . All Rights Reserved . ********************************************/ #include <map> #include <set> #include <queue> #include <stack> #include <cmath> #include <ctime> #include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> #define rep(i,a,b) for(int i = (a) ; i <= (b) ; i ++) //遍历 #define rrep(i,a,b) for(int i = (b) ; i >= (a) ; i --) //反向遍历 #define repS(it,p) for(auto it = p.begin() ; it != p.end() ; it ++) //遍历一个STL容器 #define repE(p,u) for(Edge * p = G[u].first ; p ; p = p -> next) //遍历u所连接的点 #define cls(a,x) memset(a,x,sizeof(a)) #define eps 1e-8 using namespace std; const int MOD = 1e9+7; const int INF = 0x3f3f3f3f; const int MAXN = 5e5+5; const int MAXE = 2e5+5; typedef long long LL; typedef unsigned long long ULL; int T,n,m,k; int fx[] = {0,1,-1,0,0}; int fy[] = {0,0,0,-1,1}; const int MAX_SIZE = 26; int tot ; char s[1000005]; class AC_automation { private: struct Node { int next[MAX_SIZE]; //节点的儿子 int stat ; //有几个字符是以当前节点结尾的 }t[MAXN]; //Trie 树上的节点 int fail[MAXN]; //失配指针 public: void init() { tot = 1; cls(t,0); cls(fail,0); } void insert(char * str) { int len = strlen(str) - 1; rep(i,0,len) str[i] -= 'a'; int pre = 0 , nxt = 0 ; rep(i,0,len) { nxt = t[pre].next[str[i]]; if(nxt == 0) { t[pre].next[str[i]] = tot ; nxt = tot ++; } pre = nxt; //printf("%d -> ",nxt); } //puts(""); t[nxt].stat ++; } void get_fail() { queue<int>q; q.push(0); while(!q.empty()) { int u = q.front(); rep(i,0,MAX_SIZE-1) { if(t[u].next[i]) { q.push(t[u].next[i]); int tmp = u; while(fail[tmp]) { if(t[fail[tmp]].next[i]) { fail[t[u].next[i]] = t[fail[tmp]].next[i]; break; } tmp = fail[tmp]; } if(u != 0 && !fail[t[u].next[i]]) {//处理fail[tmp] = 0 时的情况 if(t[0].next[i]) fail[t[u].next[i]] = t[0].next[i]; } } } q.pop(); } //rep(i,1,tot-1) printf("%d %d %d\n",i,fail[i],t[i].stat); } int query(char * str) { int ret = 0; int len = strlen(str) - 1; rep(i,0,len) str[i] -= 'a'; int now = 0; rep(i,0,len) { while(now && (!t[now].next[str[i]])) now = fail[now]; now = t[now].next[str[i]]; int tmp = now; while(tmp && (t[tmp].stat != -1)) { ret += t[tmp].stat; t[tmp].stat = -1; tmp = fail[tmp]; } } return ret; } }; AC_automation ac; void input() { ac.init(); scanf("%d",&n); char str[55]; rep(i,1,n) { scanf("%s",str); ac.insert(str); } ac.get_fail(); scanf("%s",s); } void solve() { printf("%d\n",ac.query(s)); } int main(void) { //freopen("a.in","r",stdin); scanf("%d",&T); while(T--) { input(); solve(); } return 0; }
相关文章推荐
- LLVM 与 Clang 介绍
- 标准I/O的三种缓冲
- 一键生成各种尺寸Icon的php脚本
- 莫比乌斯反演定理证明
- QTP之excel操作函数整理
- Flowchart.js首页、文档和下载 - 流程图插件 - 开源中国社区
- ALTERA系列FPGA时序分析(二)
- 转: Oracle Form 中commit 与do_key('commit_form')区别
- (转)sqlplus中文显示乱码的问题
- leetcode 301. Remove Invalid Parentheses
- jqeury数据缓存之data()解析
- CentOS Linux下VNC Server远程桌面配置详解
- 【LEETCODE】313-Super Ugly Number [Python]
- 补充 十进制转化十六进制
- HDU【2795】Billboard
- DebugView 远程/服务器 Invalid argument:c
- 多线程之Thread--JAVA
- HTML,CSS和JavaScript对比(一)
- 期末练习赛 构造数列 数学+模拟(兰福德数列)
- 猫猫学Swift之变量和常量(2)