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

题意:多个模板串,一个文本串,求出那些模板串在文本串中出现次数最多。

解法:AC自动机入门模板题。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <map>
#define Mod 1000000007
using namespace std;
#define N 1000007

const int MAXNODE = 20005;
const int SIZE = 26;
int cnt[MAXNODE];
struct Trie {
    int ch[MAXNODE][SIZE],val[MAXNODE],sz,fail[MAXNODE],last[MAXNODE];
    Trie() { sz = 1; memset(ch[0],0,sizeof(ch[0])); }
    int idx(char c) { return c-‘a‘; };
    void init() { sz = 1; memset(ch[0],0,sizeof(ch[0])); memset(cnt,0,sizeof(cnt)); }
    void print(int j) {
        if(j) {
            cnt[val[j]]++;
            print(last[j]);
        }
        return;
    }
    void Insert(char *s,int v) {
        int u = 0, n = strlen(s);
        for(int i=0;i<n;i++) {
            int c = idx(s[i]);
            if(!ch[u][c]) {
                memset(ch[sz],0,sizeof(ch[sz]));
                val[sz] = 0;
                ch[u][c] = sz++;
            }
            u = ch[u][c];
        }
        val[u] = v;
    }
    void getFail() {
        queue<int> q;
        fail[0] = 0;
        for(int c=0;c<SIZE;c++) {
            int u = ch[0][c];
            if(u) { fail[u] = 0; q.push(u); last[u] = 0; }
        }
        while(!q.empty()) {
            int r = q.front(); q.pop();
            for(int c=0;c<SIZE;c++) {
                int u = ch[r][c];
                if(!u) continue;
                q.push(u);
                int v = fail[r];
                while(v && !ch[v][c]) v = fail[v];
                fail[u] = ch[v][c];
                last[u] = val[fail[u]] ? fail[u] : last[fail[u]];
            }
        }
    }
    void query(char *T) {
        int n = strlen(T), j = 0;
        for(int i=0;i<n;i++) {
            int c = idx(T[i]);
            while(j && !ch[j][c]) j = fail[j];
            j = ch[j][c];
            if(val[j]) print(j);
            else if(last[j]) print(last[j]);
        }
    }
};
char T[N],ss[160][77];
map<string,int> mp;
Trie ac;

int main()
{
    int n,i;
    while(scanf("%d",&n)!=EOF && n)
    {
        mp.clear();
        ac.init();
        for(i=1;i<=n;i++) {
            scanf("%s",ss[i]);
            ac.Insert(ss[i],i);
            mp[string(ss[i])] = i;
        }
        ac.getFail();
        scanf("%s",T);
        ac.query(T);
        int Maxi = -1;
        for(i=1;i<=n;i++)
            Maxi = max(Maxi,cnt[i]);
        cout<<Maxi<<endl;
        for(i=1;i<=n;i++) {
            if(cnt[mp[string(ss[i])]] == Maxi)
                printf("%s\n",ss[i]);
        }
    }
    return 0;
}

时间: 2024-08-02 15:13:50

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

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

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

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

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

LA 4670 出现次数最多的子串 (AC自动机模板题)

Dominating Patterns Time Limit:3000MS   Memory Limit:Unknown   64bit IO Format:%lld & %llu [Submit]  [Go Back]  [Status] Description The archaeologists are going to decipher a very mysterious ``language". Now, they know many language patterns; ea

NYOJ 1085 数单词 (AC自动机模板题)

数单词 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述 为了能够顺利通过英语四六级考试,现在大家每天早上都会早起读英语. LYH本来以为自己在6月份的考试中可以通过六级,可是没想到,成绩出来以后,居然没有通过.所以他不得不付出更多的时间来学习英语. 要想通过六级,最基本的要求就是词汇量.为了能够更快的记住一些陌生单词,LYH有时会找一些英语文章来读. 今天早上,LYH又找了一篇文章.读之前,他突然萌生出一个想法:文章中哪些单词出现的次数最多呢? 输入 第一行输入一个

hdu5384 AC自动机模板题,统计模式串在给定串中出现的个数

http://acm.hdu.edu.cn/showproblem.php?pid=5384 Problem Description Danganronpa is a video game franchise created and developed by Spike Chunsoft, the series' name is compounded from the Japanese words for "bullet" (dangan) and "refutation&q

HDU 2222 Keywords Search(AC自动机模板题)

原题大意:原题链接 先给定T个单词,然后给定一个字符串,查询该字符串中包含多少个给定的单词 解题思路:AC自动机模板题 参考链接:哔哩哔哩算法讲堂 WA版本 注意:因为输入的单词可能有重复,那么Insert()函数中p->id=id;语句中p->id会被覆盖,在Query()函数中会一次性全部被清零,导致不能查询重复单词,以至于结果res错误. #include<queue> #include<cstdio> #include<cstring> using