zoukankan      html  css  js  c++  java
  • 2015 Multi-University Training Contest 8 hdu 5384 Danganronpa

    Danganronpa

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
    Total Submission(s): 318    Accepted Submission(s): 176

    Problem Description

    给你n个A串,m个B串,对每个A串,询问,这些B串们在该A串中一共出现过多少次

    Input

    样例个数

    n m

    接下来n个A串

    接下来m个B串

    Output

    如问题描述,对每个A输出...

    Sample Input
    1
    5 6
    orz
    sto
    kirigiri
    danganronpa
    ooooo
    o
    kyouko
    dangan
    ronpa
    ooooo
    ooooo
     

     

    Sample Output
    1
    1
    0
    3
    7
     


    Source
     
    解题:AC自动机自动AC
     
     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int maxn = 250010;
     4 struct trie {
     5     int word[26],fail,cnt;
     6     void init() {
     7         fail = cnt = 0;
     8         memset(word,-1,sizeof word);
     9     }
    10 } dic[maxn];
    11 int tot;
    12 char str[1000100];
    13 void insertWord(int root,char *s) {
    14     for(int i = 0; s[i]; i++) {
    15         int k = s[i]-'a';
    16         if(dic[root].word[k] == -1) {
    17             dic[++tot].init();
    18             dic[root].word[k] = tot;
    19         }
    20         root = dic[root].word[k];
    21     }
    22     ++dic[root].cnt;
    23 }
    24 queue<int>q;
    25 void build(int root) {
    26     while(!q.empty()) q.pop();
    27     q.push(root);
    28     while(!q.empty()) {
    29         int u = q.front();
    30         q.pop();
    31         for(int i = 0; i < 26; i++) {
    32             if(dic[u].word[i] == -1) continue;
    33             if(u == 0) dic[dic[u].word[i]].fail = 0;
    34             else {
    35                 int v = dic[u].fail;
    36                 while(v && dic[v].word[i] == -1) v = dic[v].fail;
    37                 if(dic[v].word[i] == -1) dic[dic[u].word[i]].fail = 0;
    38                 else dic[dic[u].word[i]].fail = dic[v].word[i];
    39             }
    40             q.push(dic[u].word[i]);
    41         }
    42     }
    43 }
    44 int query(int root,char *s) {
    45     int i,ans = 0;
    46     for(i = 0; s[i]; i++) {
    47         int k = s[i]-'a';
    48         while(root && dic[root].word[k] == -1)
    49             root = dic[root].fail;
    50         if(dic[root].word[k] != -1) {
    51             int v = dic[root].word[k];
    52             while(v) {
    53                 ans += dic[v].cnt;
    54                 v = dic[v].fail;
    55             }
    56             root = dic[root].word[k];
    57         }
    58     }
    59     return ans;
    60 }
    61 char FK[100001][10010];
    62 int main() {
    63     int n,m,t;
    64     scanf("%d",&t);
    65     while(t--) {
    66         dic[tot = 0].init();
    67         scanf("%d%d",&n,&m);
    68         for(int i = 0; i < n; ++i)
    69             scanf("%s",FK[i]);
    70         while(m--) {
    71             scanf("%s",str);
    72             insertWord(0,str);
    73         }
    74         build(0);
    75         for(int i = 0; i < n; ++i)
    76             printf("%d
    ",query(0,FK[i]));
    77     }
    78     return 0;
    79 }
    View Code

    这才是AC自动机的正确使用方法,Trie图

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int maxn = 250010;
     4 struct Trie{
     5     int ch[maxn][26],fail[maxn],cnt[maxn],tot;
     6     int newnode(){
     7         memset(ch[tot],0,sizeof ch[tot]);
     8         fail[tot] = cnt[tot] = 0;
     9         return tot++;
    10     }
    11     void init(){
    12         tot = 0;
    13         newnode();
    14     }
    15     void insert(char *str,int root = 0){
    16         for(int i = 0; str[i]; ++i){
    17             if(!ch[root][str[i]-'a'])
    18                 ch[root][str[i]-'a'] = newnode();
    19             root = ch[root][str[i]-'a'];
    20         }
    21         ++cnt[root];
    22     }
    23     void build(int root = 0){
    24         queue<int>q;
    25         for(int i = 0; i < 26; ++i)
    26             if(ch[root][i]) q.push(ch[root][i]);
    27         while(!q.empty()){
    28             root = q.front();
    29             q.pop();
    30             for(int i = 0; i < 26; ++i)
    31             if(ch[root][i]){
    32                 fail[ch[root][i]] = ch[fail[root]][i];
    33                 cnt[ch[root][i]] += cnt[ch[fail[root]][i]];
    34                 q.push(ch[root][i]);
    35             }else ch[root][i] = ch[fail[root]][i];
    36         }
    37     }
    38     int query(char *str,int ret = 0,int root = 0){
    39         for(int i = 0; str[i]; ++i){
    40             int x = root = ch[root][str[i]-'a'];
    41             ret += cnt[x];
    42         }
    43         return ret;
    44     }
    45 }ac;
    46 char FK[100001][10010],str[1000010];
    47 int main(){
    48     int kase,n,m;
    49     scanf("%d",&kase);
    50     while(kase--){
    51         ac.init();
    52         scanf("%d%d",&n,&m);
    53         for(int i = 0; i < n; ++i)
    54             scanf("%s",FK[i]);
    55         while(m--){
    56             scanf("%s",str);
    57             ac.insert(str);
    58         }
    59         ac.build();
    60         for(int i = 0; i < n; ++i)
    61             printf("%d
    ",ac.query(FK[i]));
    62     }
    63     return 0;
    64 }
    View Code
  • 相关阅读:
    ASP.NET MVC 扩展相关
    新.NET开发十大必备工具
    c#调用存储过程两种方法
    TweakUI取消pc喇叭声
    baidu mp3竟然还加密,太扯了
    NTLM在使用代理服务器的情况下,第三次握手可能出错
    httpclient解析gzip网页
    eclipse不能自动编译工程的解决方法
    bat设置环境变量
    java的ZipOutputStream压缩文件的两个问题(乱码和每次zip后文件md5变化)
  • 原文地址:https://www.cnblogs.com/crackpotisback/p/4729329.html
Copyright © 2011-2022 走看看