【AC自动机】HDU 3695 Computer Virus on Planet Pandora 裸题
2014-09-05 20:42
357 查看
n个单词在一个字符串和该串的逆串出现了几个
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> #include <string> #include <iostream> #include <algorithm> using namespace std; #include <queue> #include <stack> #include <vector> #include <deque> #include <set> #include <map> #define cler(arr, val) memset(arr, val, sizeof(arr)) #define IN freopen ("in.txt" , "r" , stdin); #define OUT freopen ("out.txt" , "w" , stdout); typedef long long LL; const int MAXN = 1000006;//点数的最大值 const int MAXM = 20006;//边数的最大值 const int INF = 11521204; const int mod=1000000007; #define maxnode 250001 #define sigma_size 26 int ans; struct Trie { int ch[maxnode][sigma_size]; int val[maxnode]; //该单词在模式串中出现的次数 int last[maxnode]; int f[maxnode]; //失配数组 int num[maxnode]; //该单词出现在文本串的次数 int pre[maxnode]; //该单词的前驱 int len[maxnode]; //以该单词结尾的单词长度 int Char[maxnode]; //该单词对应的字母 int sz; void init() { sz=1; memset(ch,0,sizeof(ch)); memset(val, 0, sizeof(val)); memset(f,0,sizeof(f)); memset(last,0,sizeof(last)); //记录该节点前一个节点是谁 memset(len, 0, sizeof(len)); } int idx(char c) { return c-'A'; } int insert(char *s) { int u = 0; for(int i = 0; s[i] ; i++) { int c = idx(s[i]); if(!ch[u][c]) ch[u][c] = sz++; u = ch[u][c]; } val[u] ++; return u; } void getFail() { queue<int> q; for(int i = 0; i<sigma_size; i++) if(ch[0][i]) q.push(ch[0][i]); 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; q.push(u); int v = f[r]; while(v && ch[v][c] == 0) v = f[v]; //沿失配边走上去 如果失配后有节点 且 其子节点c存在则结束循环 f[u] = ch[v][c]; last[u] = val[f[u]] ? f[u] : last[f[u]]; } } } void find(char *T) { int u = 0; for(int i = 0; T[i] ; i++) { int c = idx(T[i]); while(u && ch[u][c]==0) u = f[u]; u = ch[u][c]; int temp = u; while(temp && val[temp]) //沿失配边走 || 若沿失配边走时一定要节点为单词结尾则改成while(temp && val[temp]) { ans+=val[temp]; val[temp]=0; temp = f[temp]; } } return ; } } ac; char s[5110000],s1[5110000]; int main() { int t,n; // IN; scanf("%d",&t); while(t--) { ac.init(); scanf("%d",&n); for(int i=0; i<n; i++) { scanf("%s",s); ac.insert(s); } ac.getFail(); int i=0; char c; getchar(); while(c=getchar(),c>10) { if(c=='[') { int x; scanf("%d%c]",&x,&c); while(x--) s[i++]=c; } else { s[i++]=c; } } s[i]=s1[i]=0; for(int j=0;j<i;j++) s1[i-j-1]=s[j]; ans=0; ac.find(s);ac.find(s1); printf("%d\n",ans); } return 0; }
相关文章推荐
- AC自动机 - 多模式串的匹配 --- HDU 3695 Computer Virus on Planet Pandora(模板题)
- hdu 3695:Computer Virus on Planet Pandora(AC自动机,入门题)
- HDU 3695 / POJ 3987 Computer Virus on Planet Pandora(AC自动机)(2010 Asia Fuzhou Regional Contest)
- HDU 3695 Computer Virus on Planet Pandora(10年福州 AC自动机)
- 【AC自动机】HDU 3695 Computer Virus on Planet Pandora 裸题
- AC自动机 - 多模式串的匹配 --- HDU 3695 Computer Virus on Planet Pandora
- HDU 3695:Computer Virus on Planet Pandora(AC自动机裸题,数组实现AC自动机)
- hdu 3695 10 福州 现场 F - Computer Virus on Planet Pandora 暴力 ac自动机 难度:1
- HDU 3695 Computer Virus on Planet Pandora
- HDU 3695 Computer Virus on Planet Pandora (AC自动机)
- hdoj 3695 Computer Virus on Planet Pandora 【AC自动机】
- hdu 3695 Computer Virus on Planet Pandora AC自动机
- hdu 3695 Computer Virus on Planet Pandora AC自动机
- HDU 3695 Computer Virus on Planet Pandora
- hdu 3695 Computer Virus on Planet Pandora(AC自动机)
- HDU 3695 Computer Virus on Planet Pandora(AC自动机)
- HDU 3695 Computer Virus on Planet Pandora(AC自动机)
- HDU 3695 Computer Virus on Planet Pandora (AC自己主动机)
- HDU 3695 Computer Virus on Planet Pandora(自动机)
- HDU 3695-Computer Virus on Planet Pandora(ac自动机)