Submit: 1075 Solved: 367
Description
Input
注意 是0<=P
Output
Sample Input
Sample Output
HINT
30%的数据保证, n ≤ 2. 50%的数据保证, n ≤ 5. 100%的数据保证, n , l, m≤ 10.
Source
概率
AC自动机+矩阵乘法
先建好AC自动机,得到不同字母间的转移关系。
对于每个结点,如果它是某个玩家的字符串末,则它转移到自己的概率为1,否则按照读入的概率转移到不同的字母去。
↑以此构建转移矩阵。
精度要求1-e2,那么尝试矩阵暴力自乘,使得概率趋于稳定。自乘30次精度不够,会WA,40次就过了。
1 /*by SilverN*/ 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cstdio> 6 #include<cmath> 7 #include<queue> 8 using namespace std; 9 const int mxn=50; 10 int n,l,m; 11 struct Aca{ 12 int t[300][12]; 13 int fail[300],end[300]; 14 int pos[300]; 15 int cnt,rt,id; 16 void clear(){ 17 cnt=0;memset(t,0,sizeof t);memset(fail,0,sizeof fail); 18 rt=++cnt;id=0; 19 return; 20 } 21 void insert(char s[]){ 22 int len=strlen(s); 23 int now=rt; 24 for(int i=0;i<len;i++){ 25 if(!t[now][s[i]-'A']) 26 t[now][s[i]-'A']=++cnt; 27 now=t[now][s[i]-'A']; 28 } 29 end[now]++; 30 pos[++id]=now;//记录每个串末尾的结点编号 31 return; 32 } 33 void Build(){ 34 queue<int>q; 35 int i,j; 36 for(i=0;i<m;i++){ 37 if(t[rt][i]){ 38 q.push(t[rt][i]); 39 fail[t[rt][i]]=rt; 40 } 41 else t[rt][i]=rt; 42 } 43 while(!q.empty()){ 44 int u=q.front();q.pop(); 45 for(i=0;i<m;i++){ 46 if(t[u][i]){ 47 q.push(t[u][i]); 48 fail[t[u][i]]=t[fail[u]][i]; 49 } 50 else t[u][i]=t[fail[u]][i]; 51 } 52 } 53 } 54 }; 55 Aca a;//AC自动机 56 // 57 struct Matrix{ 58 double c[130][130]; 59 int x; 60 void clear(){memset(c,0,sizeof c);x=0;return;} 61 friend Matrix operator * (Matrix a,Matrix b){ 62 Matrix res; 63 res.clear(); 64 res.x=a.x; 65 for(int i=1;i<=a.x;i++){ 66 for(int j=1;j<=a.x;j++){ 67 for(int k=1;k<=a.x;k++){ 68 res.c[i][j]+=a.c[i][k]*b.c[k][j]; 69 } 70 } 71 } 72 return res; 73 } 74 }mp;//矩阵乘 75 char s[mxn]; 76 double p[mxn]; 77 int main(){ 78 int i,j,P,Q; 79 scanf("%d%d%d",&n,&l,&m); 80 for(i=1;i<=m;i++){ 81 scanf("%d%d",&P,&Q); 82 p[i]=(double)P/Q; 83 } 84 a.clear(); 85 for(i=1;i<=n;i++){ 86 scanf("%s",s); 87 a.insert(s); 88 } 89 a.Build(); 90 for(i=1;i<=a.cnt;i++){//统计概率 91 if(a.end[i]) mp.c[i][i]=1; 92 else for(j=0;j<m;j++){ 93 mp.c[i][a.t[i][j]]+=p[j+1]; 94 } 95 } 96 /* 97 for(i=1;i<=a.cnt;i++){ 98 for(j=1;j<=a.cnt;j++){ 99 printf("%.3f ",mp.c[i][j]); 100 } 101 printf(" "); 102 } 103 */ 104 mp.x=a.cnt; 105 for(i=1;i<=40;i++) 106 mp=mp*mp; 107 for(i=1;i<=n;i++) 108 printf("%.2f ",mp.c[1][a.pos[i]]); 109 return 0; 110 } 111 /* 112 3 2 2 113 1 2 114 1 2 115 AB 116 BA 117 AA 118 */