【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 int maxn = 500010;
const int maxd = 26;
struct Trie{
    int next[maxn][maxd],fail[maxn],end[maxn];
    int root,L;
    int num[101000];
    int newnode(){
        for(int i = 0;i < maxd;i++)
            next[L][i] = -1;
        end[L++] = 0;
        return L - 1;
    }
    void init(){
        L = 0;
        root = newnode();
        memset(num,0,sizeof(num));
    }
    void insert(char s[]){
        int len = strlen(s);
        int now = root;
        for(int i = 0;i < len;i++){
            if(next[now][s[i] - 'a'] == -1)
                next[now][s[i] - 'a'] = newnode();
            now = next[now][s[i] - 'a'];
        }
        end[now] ++;
    }
    void build(){
        queue<int>Q;
        fail[root] = root;
        for(int i = 0;i < maxd;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 < maxd;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]);
                }
        }
    }
    void query(string &buf,int id){
        int len = buf.size();
        int now = root;
        for(int i = 0;i < len; i++){
            now = next[now][buf[i] - 'a'];
            int temp = now;
            while(temp != root){
                num[id] += end[temp];
                temp = fail[temp];
            }
        }
    }
};
Trie ac;
char cstr[maxn];
vector<string>_find;
string _str;
int main(){
    int n,m;
    int T;
    scanf("%d",&T);
    while(T--){
        ac.init();
        scanf("%d%d",&n,&m);
        _find.clear();
        for(int i = 1; i <= n; i++){
            cin >> _str;
            _find.push_back(_str);
        }
        for(int i = 1; i <= m; i++){
            scanf("%s",cstr);
            ac.insert(cstr);
        }
        ac.build();
        for(int i = 0; i < n; i++)
            ac.query(_find[i],i);
        for(int i = 0; i < n; i++)
            printf("%d\n",ac.num[i]);
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-05 11:16:02

【HDU 5384】Danganronpa(AC自动机)的相关文章

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自动机)

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自动机)

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

HDU 5384 Danganronpa (字典树运用)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5384 题面: Danganronpa Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 512    Accepted Submission(s): 284 Problem Description Danganronpa is a vid

HDU 2222(AC自动机模板题)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2222 题目大意:多个模式串.问匹配串中含有多少个模式串.注意模式串有重复,所以要累计重复结果. 解题思路: AC自动机模板题. 一开始使用LRJ的坑爹静态模板,不支持重复的模式串. 在做AC自动机+DP的时候,扒了zcwwzdjn大神的动态优化(失配指向root)写法,以及借鉴了网上的AC自动机模板, 搞出了这么一个支持重复串的模板. #include "cstdio" #include

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

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的一个子串,也就

HDU 2296 Ring [AC自动机 DP 打印方案]

Ring Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3536 Accepted Submission(s): 1153 Problem Description For the hope of a forever love, Steven is planning to send a ring to Jane with a romantic

HDU 2296 Ring AC自动机 + DP

题意:给你n个模式串,每个模式串有一个得分,让你构造出一个长度为N之内且分数最高的文本串;输出字典序列最小的. 解题思路:  AC自动机 + DP , 不过要输出字典序列最小,多开一个 一个三维字符串来辅助二维DP(新思路) , DP[i][j] ,表示到i位置状态为j的最大得分. 解题代码: 1 // File Name: temp.cpp 2 // Author: darkdream 3 // Created Time: 2014年09月11日 星期四 15时18分4秒 4 5 #inclu

HDU 6096 String (AC自动机)

题意:给出n个字符串和q个询问,每次询问给出两个串 p 和 s .要求统计所有字符串中前缀为 p 且后缀为 s (不可重叠)的字符串的数量. 析:真是觉得没有思路啊,看了官方题解,真是好复杂. 假设原始的字符串 数组为A,首先将A中的每个字符串都进行翻转,得到字符串数组B,然后,将A和B按字典序排序. 对于一个查询来说有一个前缀p和后缀s, 所有包含前缀p的字符串在A中是连续的,可通过二分求出该区间 设为[Lp,Rp],同样,所有包含后缀s的字符串在B中也是连续的,设为[Ls,Rs] 接下来只需