【AC自动机】洛谷 P3808 【模板】AC自动机(简单版)
2021-09-26 10:54:00
# ACM
题链
题目分析
多模式串匹配,使用$AC$自动机,模板题;
学自 $OI-wiki$
代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
| #include <bits/stdc++.h> using namespace std; #define LL long long #define ULL unsigned long long #define ls rt<<1 #define rs rt<<1|1 #define B1 131 #define B2 13331 #define M1 1000000007 #define M2 1000000009 #define eps 1e-8 #define MAXN 9e18 #define MS 1000009
int n,m,k; char s[MS]; int dic[MS][26], ext[MS], fail[MS], tot; queue<int > Q;
void insert(char *s, int len){ int u = 0; for(int i=0;i<len;i++){ int c = s[i]-'a'; if(!dic[u][c]) dic[u][c] = ++tot; u = dic[u][c]; } ext[u]++; }
void build(){ for(int i=0;i<26;i++){ if(dic[0][i]) Q.push(dic[0][i]); } while(!Q.empty()){ int u = Q.front(); Q.pop(); for(int i=0;i<26;i++){ if(dic[u][i]){ fail[dic[u][i]] = dic[fail[u]][i]; Q.push(dic[u][i]); } else{ dic[u][i] = dic[fail[u]][i]; } } } }
int query(char *s, int len){ int cnt = 0; for(int i=0,u=0,c;i<len;i++){ c = s[i]-'a'; u = dic[u][c]; for(int j=u;j && ext[j];j=fail[j]){ cnt += ext[j]; ext[j] = 0; } } return cnt; }
void solve(){ cin >> n; for(int i=1;i<=n;i++){ cin >> s; insert(s, strlen(s)); } build(); cin >> s; cout << query(s, strlen(s)) << "\n"; }
int main(){ ios::sync_with_stdio(false); int ce = 1; while(ce--){ solve(); } }
|
2021-09-26 10:54:00
# ACM