bzoj1030 AC自动机+dp
思路:建状态图,在状态图上dp。
#include<bits/stdc++.h> #define LL long long #define ll long long #define fi first #define se second #define mk make_pair #define PII pair<int, int> #define y1 skldjfskldjg #define y2 skldfjsklejg using namespace std; const int N = 6000 + 7; const int M = 1e7 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 10007; int n, m; char s[N]; void add(int &a, int b) { a += b; if(a >= mod) a -= mod; } struct Ac { int ch[N][26], dp[N][100][2], val[N], f[N], tot, sz; void init(int sz) {this->sz = sz, tot = 0;}; int newNode() { tot++; f[tot] = 0; val[tot] = 0; memset(ch[tot], 0, sizeof(ch[tot])); return tot; } inline int idx(char c) {return c - 'A';} void addStr(char *s) { int u = 0; for(int i = 0; s[i]; i++) { int c = idx(s[i]); if(!ch[u][c]) ch[u][c] = newNode(); u = ch[u][c]; } val[u] = 1; } void build() { queue<int> que; for(int c = 0; c < sz; c++) { int v = ch[0][c]; if(!v) ch[0][c] = 0; else f[v] = 0, que.push(v); } while(!que.empty()) { int u = que.front(); que.pop(); val[u] |= val[f[u]]; for(int c = 0; c < sz; c++) { int v = ch[u][c]; if(!v) ch[u][c] = ch[f[u]][c]; else f[v] = ch[f[u]][c], que.push(v); } } } void solve() { memset(dp, 0, sizeof(dp)); dp[0][0][0] = 1; for(int k = 0; k < m; k++) { for(int u = 0; u <= tot; u++) { for(int c = 0; c < sz; c++) { int v = ch[u][c]; add(dp[v][k + 1][1], dp[u][k][1]); if(val[v]) add(dp[v][k + 1][1], dp[u][k][0]); else add(dp[v][k + 1][0], dp[u][k][0]); } } } int ans = 0; for(int i = 0; i <= tot; i++) add(ans, dp[i][m][1]); printf("%d\n", ans); } } ac; int main() { ac.init(26); scanf("%d%d", &n, &m); for(int i = 0; i < n; i++) { scanf("%s", s); ac.addStr(s); } ac.build(); ac.solve(); return 0; } /* 2 abad ba ----- */