忘记了 这一句 val[u] |= val[f[u]];///!!!
参考:http://blog.csdn.net/no__stop/article/details/8943271
另有:
hdu 3341 Lost's revenge关于压缩的技巧
lightoj 1427 Substring Frequency (II) (ac自动机)在fail树上的拓扑
。。。
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <ctime>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <string>
#include <set>
#include <stack>
#include <map>
#include <cmath>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
#define FE(i, a, b) for(int i = (a); i <= (b); ++i)
#define FD(i, b, a) for(int i = (b); i >= (a); --i)
#define REP(i, N) for(int i = 0; i < (N); ++i)
#define CLR(a, v) memset(a, v, sizeof(a))
#define PB push_back
#define MP make_pair
typedef long long LL;
const int INF = 0x3f3f3f3f;
const int MOD = 10007;
const int maxn = 1555;
const int SIG = 4;
int dp[2][111][maxn];
int ans1, ans2;
int n, p;
struct AC{
int ch[maxn][SIG];
int f[maxn];
int dep[maxn];
int val[maxn];
int sz;
int newnode(int deep)///!!!
{
CLR(ch[sz], 0);
dep[sz] = deep;
val[sz] = 0;
return sz++;
}
void init()
{
sz = 0;
newnode(0);
}
int idx(char c) { return c-'a'; }
void insert(char *s)
{
int u=0,n=strlen(s);
int d = 0;
for(int i=0;i<n;i++)
{
d++;
int c=idx(s[i]);
if(!ch[u][c]) ch[u][c] = newnode(d);
u = ch[u][c];
}
val[u] = 1;
}
void getFail()
{
queue<int> q;
f[0] = 0;
for(int c = 0; c < SIG; c++)
{
int u = ch[0][c];
if(u) { f[u] = 0; q.push(u); }
}
while(!q.empty())
{
int r = q.front(); q.pop();
for(int c = 0; c < SIG; c++)
{
int u = ch[r][c];
if(!u) { ch[r][c] = ch[f[r]][c]; continue; }
q.push(u);
int v = f[r];
while(v && !ch[v][c]) v = f[v];
f[u] = ch[v][c];
val[u] |= val[f[u]];///!!!
}
}
}
void solve(char *s)
{
int len = strlen(s);
CLR(dp, 0);
int fla = 0;
int uu = 0;
for (int i = 0; i < len; i++)
{
int c = idx(s[i]);
uu = ch[uu][c];
if (val[uu]) fla = 1;
}
if (fla) { ans1 = 0; ans2 = 1; return; }
dp[0][len][uu] = 1;
int now, next;
now = 0;
for (int i = 0; i <= p; i++)
{
next = now ^ 1;
for (int r = 0; r < sz; r++)
{
ans1 += dp[now][0][r];
ans1 %= MOD;///!!!
for (int j = 1; j <= 100; j++)
{
int tmp = dp[now][j][r];
if (!tmp) continue;
if (val[r]) { ans2 += tmp; ans2 %= MOD; continue; }///!!!
for (int g = 0; g < 4; g++)
{
int u = ch[r][g];
dp[next][j + 1][u] += tmp;
dp[next][j + 1][u] %= MOD;
}
if (dep[r] <= j - 1) dp[next][j - 1][r] += tmp, dp[next][j - 1][r] %= MOD;
else dp[next][j - 1][f[r]] += tmp, dp[next][j - 1][f[r]] %= MOD;
}
}
CLR(dp[now], 0);
now ^= 1;
}
}
}ac;
char s[maxn];
char ca[maxn];
int main()
{
while (~scanf("%s", s))
{
scanf("%d%d", &p, &n);
ac.init();
for (int i = 1; i <= n; i++)
{
scanf("%s", ca);
ac.insert(ca);
}
ac.getFail();
ans1 = ans2 = 0;
ac.solve(s);
printf("%d %d\n", ans1, ans2);
}
return 0;
}