【bzoj1444】[Jsoi2009]有趣的游戏

1444: [Jsoi2009]有趣的游戏

Time Limit: 10 Sec  Memory Limit: 64 MB
Submit: 1007  Solved: 334
[Submit][Status][Discuss]

Description

Input

注意 是0<=P

Output

Sample Input


Sample Output

 
 
 
 
【题解】
 
AC自动机+矩阵乘法
 
首先把模式串建成AC自动机,构建出转移矩阵。
 
构造方法:a[i][j]表示从第i个结点转移到第j个结点的概率,则如果j被标记过,f[i][j]=1,否则f[i][j]=possble[ch[j]]
 
具体见代码:
 
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<ctime>
 6 #include<cmath>
 7 #include<algorithm>
 8 using namespace std;
 9 #define MAXN 510
10 struct node{double p[MAXN][MAXN]; node(){memset(p,0,sizeof(p));}}a;
11 int n,l,m,cnt,id,fail[MAXN],end[MAXN],pos[MAXN],q[MAXN],tr[MAXN][27];
12 double chty[MAXN];
13 char ch[MAXN];
14 inline int read()
15 {
16     int x=0,f=1;  char ch=getchar();
17     while(!isdigit(ch))  {if(ch=='-')  f=-1;  ch=getchar();}
18     while(isdigit(ch))  {x=x*10+ch-'0';  ch=getchar();}
19     return x*f;
20 }
21 void insert()
22 {
23     int now=0;
24     for(int i=1;i<=l;i++) 
25     {
26         if(!tr[now][ch[i]-'A'])  tr[now][ch[i]-'A']=++cnt;
27         now=tr[now][ch[i]-'A'];
28     }
29     end[now]=1;  pos[++id]=now;
30 }
31 void build()
32 {
33     int head=0,tail=0;
34     for(int i=0;i<m;i++)  if(tr[0][i])  q[++tail]=tr[0][i];
35     while(++head<=tail)
36     {
37         int x=q[head];  end[x]|=end[fail[x]];
38         for(int i=0;i<m;i++)
39         {
40             if(!tr[x][i])  tr[x][i]=tr[fail[x]][i];
41             else {fail[tr[x][i]]=tr[fail[x]][i];  q[++tail]=tr[x][i];}
42         }
43     }
44 }
45 void get()
46 {
47     for(int i=0;i<=cnt;i++)
48     {
49         if(end[i]) a.p[i][i]=1;
50         else for(int x=0;x<m;x++) a.p[i][tr[i][x]]+=chty[x];
51     }
52 }
53 inline node operator *(node &x,node &y)
54 {
55     node z;
56     for(int i=0;i<=cnt;i++)
57         for(int j=0;j<=cnt;j++)
58             for(int k=0;k<=cnt;k++)
59                 z.p[i][j]+=x.p[i][k]*y.p[k][j];
60     return z;
61 }
62 int main()
63 {
64     //freopen("cin.in","r",stdin);
65     //freopen("cout.out","w",stdout);
66     n=read();  l=read();  m=read();
67     for(int i=0;i<m;i++)  chty[i]=(double)read()/read();
68     for(int i=1;i<=n;i++)  {scanf("%s",ch+1);  insert();}
69     build();
70     get();
71     for(int i=1;i<=50;i++)  a=a*a;
72     for(int i=1;i<=n;i++)  printf("%.2lf
",(double)a.p[0][pos[i]]);
73     return 0;
74 }
 
 
 
 
原文地址:https://www.cnblogs.com/chty/p/6008626.html