shjwudp

导航

 

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5384

题意:函数f(A, B)定义:A、B为字符串,f(A, B)为A中有多少个不同的B(ex:f("ababa", "aba")==2   f("ababa", "bab")==1),现在给你一组A串,一组B串,问你对每个A串的是多少

解:ac自动机模板题,可以把A串用'z'+1,连成一个串处理起来比较方便

  1 /*
  2  * Problem:  hdu5384 Danganronpa
  3  * Author:  SHJWUDP
  4  * Created Time:  2015/8/13 星期四 14:38:23
  5  * File Name: 1006.cpp
  6  * State: Accepted
  7  * Memo: ac自动机
  8  */
  9 #include <iostream>
 10 #include <cstdio>
 11 #include <vector>
 12 #include <cstring>
 13 #include <algorithm>
 14 #include <queue>
 15 
 16 using namespace std;
 17 
 18 const int MaxA=1e5+7;
 19 const int MaxB=7e5+7;
 20 
 21 const int SIGMA_SIZE=27;
 22 
 23 struct AhoCorasickAutomata {
 24     int ch[MaxB][SIGMA_SIZE];
 25     int val[MaxB];
 26     int sz;
 27     int f[MaxB], last[MaxB];
 28 
 29     int newNode() {
 30         memset(ch[sz], 0, sizeof(ch[sz]));
 31         val[sz]=0;
 32         return sz++;
 33     }
 34 
 35     void init() {
 36         sz=0;
 37         newNode();
 38     }
 39 
 40     int id(char c) { 
 41         return c-'a'; 
 42     }
 43 
 44     void insert(char* p) {
 45         int u=0;
 46         while(*p) {
 47             int c=id(*p++);
 48             if(!ch[u][c]) ch[u][c]=newNode();
 49             u=ch[u][c];
 50         }
 51         val[u]++;
 52     }
 53 
 54     void getFail() {
 55         queue<int> Q;
 56         f[0]=0;
 57         for(int c=0; c<SIGMA_SIZE; c++) {
 58             int u=ch[0][c];
 59             if(u) { f[u]=0; Q.push(u); last[u]=0; }
 60         }
 61 
 62         while(!Q.empty()) {
 63             int r=Q.front(); Q.pop();
 64             for(int c=0; c<SIGMA_SIZE; c++) {
 65                 int u=ch[r][c];
 66                 if(!u) { ch[r][c]=ch[f[r]][c]; continue; }
 67                 Q.push(u);
 68                 int v=f[r];
 69                 while(v && !ch[v][c]) v=f[v];
 70                 f[u]=ch[v][c];
 71                 last[u]=val[f[u]]?f[u]:last[f[u]];
 72             }
 73         }
 74     }
 75 
 76     long long dealAns(int u) {
 77         long long res=0;
 78         while(u) {
 79             res+=val[u];
 80     //        val[u]=0;
 81             u=last[u];
 82         }
 83         return res;
 84     }
 85 
 86     void find(char * T, long long * ans) {
 87         int u=0;
 88         int pos=1;
 89         long long sum=0, ltsum=0;
 90         for(int i=0; T[i]; i++) {
 91             int c=id(T[i]);
 92             u=ch[u][c];
 93             if(val[u]) sum+=dealAns(u);
 94             else if(last[u]) sum+=dealAns(last[u]);
 95             if(T[i]=='z'+1) {
 96                 ans[pos++]+=sum-ltsum;
 97                 ltsum=sum;
 98             }
 99         }
100     }
101 } ac;
102 
103 int n, m;
104 char str[MaxB];
105 long long ans[MaxA];
106 char gogogo[MaxA];
107 int main() {
108 #ifndef ONLINE_JUDGE
109     freopen("in", "r", stdin);
110     //freopen("out", "w", stdout);
111 #endif
112     int T;
113     scanf("%d", &T);
114     while(T--) {
115         scanf("%d%d", &n, &m);
116         int len=0;
117         for(int i=0; i<n; i++) {
118             scanf("%s", str+len);
119             while(str[len]) len++;
120             str[len++]='z'+1;
121         }
122         str[len]='\0';
123         ac.init();
124         for(int i=0; i<m; i++) {
125             scanf("%s", gogogo);
126             ac.insert(gogogo);
127         }
128         ac.getFail();
129         memset(ans, 0, sizeof(ans));
130         ac.find(str, ans);
131         for(int i=1; i<=n; i++) {
132             printf("%I64d\n", ans[i]);
133         }
134     }
135     return 0;
136 }
View Code

 

posted on 2015-08-13 17:26  shjwudp  阅读(306)  评论(0编辑  收藏  举报