UVALive - 4670 Dominating Patterns AC 自动机

input

n 1<=n<=150

word1

word2

...

wordn

1<=len(wirdi)<=70

s 1<=len(s)<=1000000

output

最多出现次数

出现最多的串,按输入顺序输出,可能出现相同串,也要输出

做法:用一个end数组记下每个串结尾的字符的下标,对应val为1,每次找到就将val++,然后找到最大的val,输出最大val对应的字符串

  1 #include <cstdio>
  2 #include <queue>
  3 #include <cstring>
  4 #include <iostream>
  5 #include <cstdlib>
  6 #include <algorithm>
  7 #include <vector>
  8 #include <map>
  9 #include <set>
 10 #include <ctime>
 11 #include <cmath>
 12 #include <cctype>
 13 #define MAX 100000
 14 #define LL long long
 15 int cas=1,T,n,sz,maxt,last[160*80],f[160*80],ch[160*80][26],val[160*80],end[160];
 16 char s[MAX*10+10],word[160][80];
 17 int idx(char&c) {return c-‘a‘;}
 18 void inittrie()
 19 {
 20     memset(ch[0],0,sizeof(ch[0]));
 21     sz=1;
 22     val[0]=0;
 23 }
 24 int insert(char*s)
 25 {
 26     int u=0;
 27     for(;*s;s++)
 28     {
 29         int c=idx(*s);
 30         if(!ch[u][c])
 31         {
 32             memset(ch[sz],0,sizeof(ch[0]));
 33             val[sz]=0;
 34             ch[u][c]=sz++;
 35         }
 36         u=ch[u][c];
 37     }
 38     val[u]=1;
 39     return u;
 40 }
 41 void getFail()
 42 {
 43     std::queue<int>q;
 44     f[0]=0;
 45     for(int c=0;c<26;c++)
 46     {
 47         int u=ch[0][c];
 48         if(u) { f[u]=0;q.push(u);last[u]=0; }
 49     }
 50     while(!q.empty())
 51     {
 52         int r=q.front();q.pop();
 53         for(int c=0;c<26;c++)
 54         {
 55             int u=ch[r][c];
 56             if(!u){ ch[r][c]=ch[f[r]][c];continue; }
 57             q.push(u);
 58             int v=f[r];
 59             while(v&&!ch[v][c]) v=f[v];
 60             f[u]=ch[v][c];
 61             last[u]=val[f[u]]?f[u]:last[f[u]];
 62         }
 63     }
 64 }
 65 void print(int j)
 66 {
 67     if(j)
 68     {
 69         if(val[j]) val[j]++;
 70         print(last[j]);
 71     }
 72 }
 73 void find(char*s)
 74 {
 75     int n=strlen(s);
 76     int j=0;
 77     for(int i=0;i<n;i++)
 78     {
 79         int c=idx(s[i]);
 80         j=ch[j][c];
 81         //printf("val[%d]=%d\n",j,val[j]);
 82         //if(val[j]) val[j]++;
 83         //else if(last[j]) val[last[j]]++;
 84         if(val[j]) print(j);
 85         else if(last[j]) print(last[j]);
 86     }
 87 }
 88 int main()
 89 {
 90     //freopen("/home/user/桌面/in","r",stdin);
 91     //scanf("%d\n",&T);
 92     while(scanf("%d",&n)==1&&n)
 93     {
 94         inittrie();
 95         for(int i=0;i<n;i++)
 96         {
 97             scanf("%s",word[i]);
 98             end[i]=insert(word[i]);
 99         }
100         maxt=-1;
101 //        for(int i=0;i<n;i++) printf("%d %d %s\n",end[i],val[end[i]],word[i]);
102         getFail();
103         scanf("%s",s);
104         find(s);
105         for(int i=0;i<n;i++) maxt=std::max(maxt,val[end[i]]);
106         printf("%d\n",maxt-1);
107         for(int i=0;i<n;i++) if(val[end[i]]==maxt) puts(word[i]);
108     }
109     //printf("time=%.3lf",(double)clock()/CLOCKS_PER_SEC);
110     return 0;
111 }

时间: 2024-10-15 05:47:07

UVALive - 4670 Dominating Patterns AC 自动机的相关文章

UVALive 4670 Dominating Patterns --AC自动机第一题

题意:多个模板串,一个文本串,求出那些模板串在文本串中出现次数最多. 解法:AC自动机入门模板题. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <algorithm> #include <string> #include <vector> #in

LA 4670 Dominating Patterns (AC自动机)

题意:给定一个一篇文章,然后下面有一些单词,问这些单词在这文章中出现过几次. 析:这是一个AC自动机的裸板,最后在匹配完之后再统计数目就好. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <string> #include <cstdlib> #include <cmath> #include <ios

uva 1449 - Dominating Patterns(AC自动机)

题目练级:uva 1449 - Dominating Patterns 题目大意:有一个由小写字母组成的字符串集和一个文本T,要求找出那些字符串在文本中出现的次数最多. 解题思路:将字符串集建立AC自动机,然后传入T进行匹配,对每个匹配上的字符串多应次数加1,最后找出最大值.出现次数与最大值相同的字符串输出.注意字符集中出现相同字符的情况. #include <cstdio> #include <cstring> #include <queue> #include &l

uvalive 4670 Dominating Patterns

在文本串中找出现次数最多的子串. 思路:AC自动机模板+修改一下print函数. 1 #include<stdio.h> 2 #include<math.h> 3 #include<stdio.h> 4 #include<stdlib.h> 5 #include<iostream> 6 #include<string> 7 #include<memory.h> 8 #include<map> 9 #includ

LA4670 Dominating Patterns AC自动机模板

Dominating Patterns 每次看着别人的代码改成自己的模板都很头大...空间少了个0卡了好久 裸题,用比map + string更高效的vector代替蓝书中的处理方法 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <algorithm> 6 #include <queue> 7

LA 4670 Dominating Patterns (AC自动机)

题意:给定n个字符串和一个文本串,查找哪个字符串出现的次数的最多. 析:一匹配多,很明显是AC自动机.只需要对原来的进行修改一下,就可以得到这个题的答案, 计算过程中,要更新次数,并且要映射字符串.如果用KMP肯定会超时. 代码如下: #include <iostream> #include <cstdio> #include <cstring> #include <map> #include <string> #include <queu

UVALive - 4811 Growing Strings (AC自动机+dp)

题目链接:UVALive - 4811 Growing Strings 题意: 给你n个字符串,问你最多能选出多少个字符串,使得s[i]是s[i+1]的子串. 题解: 先将所有的字符串插入AC自动机,将所有字符串按长度排序后,显然dp[i]=max{dp[j]}+1,其中s[j]是s[i]的子串.然后就完了. 1 #include<bits/stdc++.h> 2 #define mst(a,b) memset(a,b,sizeof(a)) 3 #define F(i,a,b) for(int

AC自动机 LA 4670 Dominating Patterns

题目传送门 题意:训练之南(P216) 分析:求出现最多次数的字串,那么对每个字串映射id,cnt记录次数求最大就可以了. #include <bits/stdc++.h> using namespace std; const int N = 150 + 5; const int NODE = N * 70; const int LEN = 1e6 + 5; const int SIZE = 26; struct AC { int ch[NODE][SIZE], fail[NODE], val

Dominating Patterns (AC 自动鸡模版题, 出现次数最多的子串)

传送门 题意: 给你n个模式串, 再给你一个 文本串,问模式串在文本串中出现次数最多是多少. 出现次数最多的模式串有哪些. 解: 模版题. #include <bits/stdc++.h> #define LL long long #define rep(i, j, k) for(int i = j; i <= k; i++) #define dep(i, j, k) for(int i = k; i >= j; i--) #define mem(i, j) memset(i, j