UVAlive-4670-Dominating Patterns(AC自动机)
2017-08-28 17:42
405 查看
题目链接
题意:n个模式串,一个匹配串,求每一个模式串在匹配串中出现的次数。
思路:AC自动机模板题
#include<cstdio> #include<cmath> #include<cstring> #include<algorithm> #include<iostream> #include<time.h> #include<set> #include<stack> #include<vector> #include<map> #include<queue> #define pi acos(-1) #define maxn 300 #define maxm 1001111 #define INF 0x3F3F3F3F #define eps 1e-8 #define pb push_back #define mem(a) memset(a,0,sizeof a) using namespace std; const long long mod = 1000000007; /**lyc**/ char str[maxn][77]; ///模式串 int n; char a[maxm]; #define STAUTS_NUM 50000 struct trie { ///next,fail,end都是基于第几个状态 状态就是一个字符串顺序 int next[STAUTS_NUM][26], ///next数组表示 next[i][j]表示第i个状态后连j字符会变成什么状态, ///注意最开始初始化的状态,在后面会被不断的优化 fail[STAUTS_NUM], ///失配数组,表示应该回到一个之前已匹配部分的最长后缀那里开始重新匹配。类似kmp end[STAUTS_NUM]; ///实际上就是表示哪些序列是模式串中有的,1,0,表示 // int next2[maxn][26]; /**这个数组是我这个程序中另外设的,用来储存最原始的next数组,有特殊用**/ int num[maxn];///每个单词出现的次数 int f[STAUTS_NUM];///每个节点对应的单词编号 int root, ///根节点状态,默认是0 cnt; ///状态数 int new_node () { ///对于一个没有的状态,对他新建一个节点 memset (next[cnt], -1, sizeof next[cnt]); end[cnt++] = 0; return cnt-1; } void init () { ///初始化这棵字典树 cnt = 0; root = new_node (); memset (num, 0, sizeof num); memset (f, -1, sizeof f); } 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]++; f[now] = pos; ///标记一下这个状态对应第几个字符串 } void build () { ///构建fail数组 /**这里备份一下next数组 for(int i = 0; i < cnt; i++) { for(int j = 0; j < 26; j++) { next2[i][j] = next[i][j]; } } 这里备份一下next数组**/ 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) { if (end[tmp]) { num[f[tmp]] += end[tmp]; // end[tmp] = 0; ///问题求的是多少把钥匙能够匹配, /// } tmp = fail[tmp];//沿着失配边走 } } int MAX = 0; for(int i = 1; i <= n; i++) MAX = max(MAX, num[i]); printf("%d\n", MAX); for(int i = 1; i <= n; i++) { if(num[i] == MAX) { printf("%s\n", str[i]); } } } }ac; int main() { while(scanf("%d", &n) && n) { ac.init(); for(int i = 1; i <= n; i++) { scanf("%s", str[i]); ac.insert(str[i], i); } ac.build(); scanf("%s", a); ac.query(a); } return 0; }
相关文章推荐
- UVALive 4670 (AC自动机)
- UVALive 4670 - Dominating Patterns (AC自动机)
- 文章标题 UVALive 4670 : Dominating Patterns (AC自动机模板题)
- UVALive 4670 Dominating Patterns(AC自动机模板题)
- (AC自动机)UVALive - 4670 Dominating Patterns
- UVALive-4670 Dominating Patterns / 洛谷 3796 【模板】AC自动机
- UVALive 4670 Dominating Patterns (AC自动机)
- UVALive 4811 Growing Strings【AC自动机+简单dp】
- UVALive 5103 / HDU 3695 Computer Virus on Planet Pandora(AC自动机裸)
- uvalive 3907 Puzzle (ac自动机+有向图判环+dp)
- UVALive 4670 Dominating Patterns(AC自动机)
- UVALive - 4670 Dominating Patterns AC 自动机
- UVALive 4126 Password Suspects (AC自动机+DP)
- UVA LA 4670(AC自动机)
- UVALive 3490 Generator(AC自动机+dp+高斯消元)
- UVALive-4126 AC自动机
- uva-1449-AC自动机
- UVa 11468 Substring (AC自动机+概率DP)
- UVALive 4657 Top 10(自动机)
- UvaLive-4670-Dominating Patterns