给你一个字符串集
构造一个串 S, S , 每个位置你有 pi p i 的概率插入第 i i 个字符
问字符串集中每个字符串最先出现在构造的串中的概率
涉及到字符串匹配首先想到建立 AC A C 自动机
考虑在 trie t r i e 图上 DP D P
设 f[u] f [ u ] 表示 u u 状态在 S S 中出现的概率
如果 u u 不是终止节点 , , 那么有
可以看出这个转移是成环的 , , 所以需要高斯消元
注意到所有字符串集中的字符串出现概率和为 1 1
设 idi i d i 表示第 i i 个字符串在 trie t r i e 图上的位置
即 ∑if[id[i]]=1, ∑ i f [ i d [ i ] ] = 1 , 随意替换掉一个方程就可以了
注意特判 0.00 0.00
#include
#define fp(i,a,b) for(register int i=a,I=b+1;i
#define fd(i,a,b) for(register int i=a,I=b-1;i>I;--i)
#define go(u) for(register int i=fi[u],v=e[i].to;i;v=e[i=e[i].nx].to)
#define file(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
template<class T>inline bool cmax(T&a,const T&b){return a1:0;}
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
using namespace std;
char ss[1<<17],*A=ss,*B=ss;
inline char gc(){return A==B&&(B=(A=ss)+fread(ss,1,1<<17,stdin),A==B)?-1:*A++;}
template<class T>inline void sd(T&x){
char c;T y=1;while(c=gc(),(c<48||571)if(c==45)y=-1;x=c-48;
while(c=gc(),4758)x=x*10+c-48;x*=y;
}
inline void Sd(char*s){char c;while(c=gc(),c<32);*s++=c;while(c=gc(),c>32)*s++=c;}
const int N=120;
const double eps=1e-12;
typedef int arr[N];
typedef double db;
int n,m,l;arr id;db p[N],ans[N],G[N][N];
struct ACAM{
int Cnt,ch[N][26];arr ex,fail;char s[N];
#define v (ch[u][i])
inline int ins(){
Sd(s);int u=0,i;
fp(j,0,l-1)i=s[j]-'A',u=!v?v=++Cnt:v;
ex[u]=1;return u;
}
inline void gf(){
static int q[N];int u=0,i,h=1,t=0;
fp(i,0,m)if(v)q[++t]=v;fail[0]=-1;
while(h<=t)for(u=q[h++],i=0;i<=m;++i)v?fail[q[++t]=v]=ch[fail[u]][i]:v=ch[fail[u]][i];
}
inline void build(){
fp(u,0,Cnt)G[u+1][u+1]=1;
fp(u,0,Cnt)if(!ex[u])fp(i,0,m)G[v+1][u+1]-=p[i];
fp(u,0,Cnt)G[1][u+1]=ex[u];G[1][Cnt+2]=1;
}
#undef v
}ac;
inline int cmp(db x){return fabs(x)0:x<0?-1:1;}
inline void Gauss(int n){
db t;int mx;
fp(i,1,n){mx=i;
fp(j,i,n)if(fabs(G[mx][i])<fabs(G[j][i]))mx=j;
if(mx^i)fp(j,i,n+1)swap(G[mx][j],G[i][j]);
fp(j,i+1,n)if(cmp(G[j][i])){
t=G[j][i]/G[i][i];
fp(k,i,n+1)G[j][k]-=G[i][k]*t;
}
}
fd(i,n,1){
fp(j,i+1,n)G[i][n+1]-=G[i][j]*ans[j];
ans[i]=G[i][n+1]/G[i][i];
}
}
int main(){
#ifndef ONLINE_JUDGE
file("s");
#endif
sd(n),sd(l),sd(m);int a,b;--m;
fp(i,0,m)sd(a),sd(b),p[i]=(db)a/b;
fp(i,1,n)id[i]=ac.ins();
ac.gf();ac.build();
Gauss(ac.Cnt+1);
fp(i,1,n)if(ans[id[i]+1]>0)printf("%.2lf\n",ans[id[i]+1]);else puts("0.00");
return 0;
}