您的位置:首页 > Web前端 > JavaScript

【bzoj1444】[Jsoi2009]有趣的游戏

2016-10-28 17:10 369 查看

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\n",(double)a.p[0][pos[i]]);
73     return 0;
74 }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: