hdu5384(2015多校8)--Danganronpa(AC自动机)

题目链接:点击打开链接

题目大意:给出n个字符串主串,和m个模式串,定义f(A,B)为B串在A串中出现的次数,现在对每一个A串都计算

∑f(Ai,Bj) (1 <= j <= m),并输出。

对m个模式串建立AC自动机,然后每个主串都放入自动机中,统计主串包含多少B内的串,并输出。

注意:

标记的时候直接累加值,可能会有多个模式串相同。

统计的时候,使用fail一直要回到根。

#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std ;
#define LL __int64
#pragma comment(linker, "/STACK:102400000,102400000")
struct node
{
    int data ;
    node *next[26] , *fail ;
};
string str[10010] , s ;
LL sum ;
queue <node*> que ;
node *newnode()
{
    node *p = new node ;
    p->data = 0 ;
    p->fail = NULL ;
    for( int i = 0 ; i < 26 ; i++)
        p->next[i] = NULL ;
    return p ;
}
void settree(node *rt)
{
    int i , k , l = s.size() ;
    node *p = rt ;
    for(i = 0 ; i < l ; i++)
    {
        k = s[i] - 'a' ;
        if( p->next[k] == NULL )
            p->next[k] = newnode() ;
        p = p->next[k] ;
    }
    p->data++ ;
}
void setfail(node *rt)
{
    int i ;
    node *p , *temp ;
    while( !que.empty() ) que.pop() ;
    que.push(rt) ;
    while( !que.empty() )
    {
        p = que.front() ;
        que.pop() ;
        for(i = 0 ; i < 26 ; i++)
        {
            if( p->next[i] )
            {
                temp = p->fail ;
                while( temp && !temp->next[i] )
                    temp = temp->fail ;
                p->next[i]->fail = temp ? temp->next[i] : rt ;
                que.push(p->next[i]) ;
            }
            else
                p->next[i] = p == rt ? rt : p->fail->next[i] ;
        }
    }
    return ;
}
void query(int u,node *rt)
{
    int i , k , l = str[u].size() ;
    node *p = rt , *temp ;
    for(i = 0 ; i < l ; i++)
    {
        if( str[u][i] < 'a' || str[u][i] > 'z' )
        {
            p = rt ;
            continue ;
        }
        k = str[u][i] - 'a' ;
        p = p->next[k] ;
        for( temp = p ; temp ; temp = temp->fail ) {
            sum += temp->data ;
        }
    }
    return ;
}
int main()
{
    int n , m , i , t ;
    node *rt ;
    scanf("%d", &t) ;
    while( t-- ) {
        rt = newnode() ;
        scanf("%d %d", &n, &m) ;
        for(i = 0 ; i < n ; i++)
            cin >> str[i] ;
        for(i = 0 ; i < m ; i++) {
            cin >> s ;
            settree(rt) ;
        }
        setfail(rt) ;
        for(i = 0 ; i < n ; i++) {
            sum = 0 ;
            query(i,rt) ;
            printf("%I64d\n", sum) ;
        }
    }
    return 0;
}

版权声明:转载请注明出处:http://blog.csdn.net/winddreams

时间: 2024-12-20 01:16:33

hdu5384(2015多校8)--Danganronpa(AC自动机)的相关文章

hdu5384 Danganronpa(AC自动机)

题目: Danganronpa Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 827    Accepted Submission(s): 443 Problem Description Danganronpa is a video game franchise created and developed by Spike Chu

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 5384 Danganronpa(AC自动机)

Danganronpa Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 429    Accepted Submission(s): 248 Problem Description Danganronpa is a video game franchise created and developed by Spike Chunsof

HDU 5384——Danganronpa——————【AC自动机】

Danganronpa Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 582    Accepted Submission(s): 323 Problem Description Danganronpa is a video game franchise created and developed by Spike Chunsoft

hdu 5384 Danganronpa(基础AC自动机)

题意:多个模式串和多个待匹配串,求每个待匹配串对于所有模式串的匹配个数: 思路:1.与最裸的ac自动机的区别在于讯问后的叶子节点的count值会改变,在每次询问时count值不要清零: 2.对于多个串的保存直接用二维数组: #include<cstdio> #include<vector> #include<iostream> #include<algorithm> #include<cstring> using namespace std; c

【HDU 5384】Danganronpa(AC自动机)

看官方题解貌似就是个自动机裸题 比赛的时候用kuangbin的AC自动机模板瞎搞的,竟然A了,而且跑的还不慢.. 存下模板吧 #include<cstdio> #include<cstring> #include<string> #include<queue> #include<vector> #include<iostream> #include<algorithm> using namespace std; const

2017多校第8场 HDU 6138 Fleet of the Eternal Throne AC自动机或者KMP

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6138 题意:给n个串,每次询问x号串和y号串的最长公共子串的长度,这个子串必须是n个串中某个串的前缀 解法1:AC自动机.做法是把n个串建成AC自动机,前缀树中每个节点都当做结尾节点,val赋为trie树深度,然后把x串丢进自动机里,把匹配到的前缀节点染个色,再把y串丢进去,遇到同样颜色的前缀节点就更新一下答案. #include <bits/stdc++.h> using namespace s

2017多校第6场 HDU 6096 String AC自动机

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6096 题意:给了一些模式串,然后再给出一些文本串的不想交的前后缀,问文本串在模式串的出现次数. 解法: 因为要求前缀后缀都包含的个数,所以可以把字符串a转换成a#a这样一个字符串,比如abca就转换成abca#abca 然后对于一组前缀a后缀b转换成b{a,比如ab ca,就是ca{ab, 然后对前缀后缀的串建立AC自动机,让主串去匹配,如上述例子,ca{ab满足为abca{abca的一个子串,也就

BZOJ 1009: [HNOI2008]GT考试 AC自动机+矩阵快速幂

经典题目了....虽然只有一个不能出现的字符串,但还是写了ac自动机 1009: [HNOI2008]GT考试 Time Limit: 1 Sec  Memory Limit: 162 MB Submit: 2051  Solved: 1257 [Submit][Status][Discuss] Description 阿申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9),他不希望准考证号上出现不吉利的数字.他的不吉利数学A1A2...Am(0<=Ai<