分析
如果字符串的长度大一点可以用矩阵快速幂来做,因为数据范围比较小,可以用DP来代替
我们去枚举每一位在a自动机中的位置,再去枚举下一位的位置,判断是否打过标记,然后进行状态转移
需要注意的是,如果输入字符是负数,需要增加一个偏移量
最后需要再写一个大数
最后吐槽一句,poj的编译器真老。。。
代码
#include <cstdio>
#include <cstring>
#include <queue>
#include <map>
#include <vector>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PII;
typedef vector<int> VI;
const int INF = 0x3f3f3f3f;
const int N = 150;
const ll mod= 1000000007;
const double eps = 1e-9;
map<char,int> M;
int tr[N][52],idx;
int ne[N];
int cnt[N];
char str[N];
int q[N];
int n,m,llll;
void insert(){
int p = 0;
for(int i = 0;str[i];i++){
int t = M[str[i] + 200];
if(!tr[p][t]) tr[p][t] = ++idx;
p = tr[p][t];
}
cnt[p] = 1;
}
void build(){
int hh = 0,tt = -1;
for(int i = 0;i < m;i++)
if(tr[0][i])
q[++tt] = tr[0][i];
while(hh <= tt){
int t = q[hh++];
for(int i = 0;i < m;i++){
int c = tr[t][i];
if(!c) tr[t][i] = tr[ne[t]][i];
else{
ne[c] = tr[ne[t]][i];;
cnt[c] |= cnt[ne[c]];
q[++tt] = c;
}
}
}
}
struct BigInteger{
int A[25];
enum{
MOD = 10000};
BigInteger(){
memset(A, 0, sizeof(A)); A[0]=1;}
void set(int x){
memset(A, 0, sizeof(A)); A[0]=1; A[1]=x;}
void print(){
printf("%d", A[A[0]]);
for (int i=A[0]-1; i>0; i--){
if (A[i]==0){
printf("0000"); continue;}
for (int k=10; k*A[i]<MOD; k*=10) printf("0");
printf("%d", A[i]);
}
printf("\n");
}
int& operator [] (int p) {
return A[p];}
const int& operator [] (int p) const {
return A[p];}
BigInteger operator + (const BigInteger& B){
BigInteger C;
C[0]=max(A[0], B[0]);
for (int i=1; i<=C[0]; i++)
C[i]+=A[i]+B[i], C[i+1]+=C[i]/MOD, C[i]%=MOD;
if (C[C[0]+1] > 0) C[0]++;
return C;
}
BigInteger operator * (const BigInteger& B){
BigInteger C;
C[0]=A[0]+B[0];
for (int i=1; i<=A[0]; i++)
for (int j=1; j<=B[0]; j++){
C[i+j-1]+=A[i]*B[j], C[i+j]+=C[i+j-1]/MOD, C[i+j-1]%=MOD;
}
if (C[C[0]] == 0) C[0]--;
return C;
}
};
BigInteger f[N][N];
int main(){
scanf("%d%d%d",&m,&n,&llll);
scanf("%s",str);
for(int i = 0;i < m;i++){
M[str[i] + 200] = i;
}
while(llll--){
scanf("%s",str);
insert();
}
build();
f[0][0].set(1);
for(int i = 1;i <= n;i++)
for(int j = 0;j <= idx;j++){
if(cnt[j]) continue;
for(int k = 0;k < m;k++){
int tj = tr[j][k];
if(cnt[tj]) continue;
f[i][tj] = f[i][tj] + f[i - 1][j];
}
}
BigInteger res;
for(int i = 0;i <= idx;i++) res = res + f[n][i];
res.print();
return 0;
}
/**
* ┏┓ ┏┓+ +
* ┏┛┻━━━┛┻┓ + +
* ┃ ┃
* ┃ ━ ┃ ++ + + +
* ████━████+
* ◥██◤ ◥██◤ +
* ┃ ┻ ┃
* ┃ ┃ + +
* ┗━┓ ┏━┛
* ┃ ┃ + + + +Code is far away from
* ┃ ┃ + bug with the animal protecting
* ┃ ┗━━━┓ 神兽保佑,代码无bug
* ┃ ┣┓
* ┃ ┏┛
* ┗┓┓┏━┳┓┏┛ + + + +
* ┃┫┫ ┃┫┫
* ┗┻┛ ┗┻┛+ + + +
*/