传送门
首先得到AC自动机。
然后得到转移矩阵。
我们可以将矩阵自乘50次,假装他是对的。
然后就这样被水过去了
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
#define N 505
using namespace std;
struct matrix{
double p[N][N];
matrix(){
memset(p,0,sizeof(p));
}
}a;
int n,l,m,cnt,id,x,y;
int fail[N],end[N],pos[N],q[N],ch[N][27];
double p[N];
char s[N];
void insert(){
int x=0;
for (int i=1;i<=l;i++){
if (!ch[x][s[i]-'A'])
ch[x][s[i]-'A']=++cnt;
x=ch[x][s[i]-'A'];
}
end[x]=1;
pos[++id]=x;
}
void build(){
int h=0,t=0;
for (int i=0;i<m;i++)
if (ch[0][i]) q[++t]=ch[0][i];
while (h<t){
int x=q[++h];
end[x]|=end[fail[x]];
for (int i=0;i<m;i++)
if (!ch[x][i]) ch[x][i]=ch[fail[x]][i];
else{
fail[ch[x][i]]=ch[fail[x]][i];
q[++t]=ch[x][i];
}
}
}
void get(){
for (int i=0;i<=cnt;i++)
if (end[i]) a.p[i][i]=1;
else
for (int j=0;j<m;j++)
a.p[i][ch[i][j]]+=p[j];
}
inline matrix operator *(matrix &x,matrix &y){
matrix z;
for (int i=0;i<=cnt;i++)
for (int j=0;j<=cnt;j++)
for (int k=0;k<=cnt;k++)
z.p[i][j]+=x.p[i][k]*y.p[k][j];
return z;
}
int main(){
scanf("%d%d%d",&n,&l,&m);
for (int i=0;i<m;i++){
scanf("%d%d",&x,&y);
p[i]=(double)x/y;
}
for (int i=1;i<=n;i++){
scanf("%s",s+1);
insert();
}
build();
get();
for (int i=1;i<=50;i++) a=a*a;
for (int i=1;i<=n;i++)
printf("%.2lf\n",a.p[0][pos[i]]);
}