zoukankan      html  css  js  c++  java
  • [BZOJ1444]有趣的游戏(AC自动机+矩阵乘法)

    n个等长字符串,机器会随机输出一个字符串(每个字母出现的概率为p[i]),问每个字符串第一个出现的概率是多少。

    显然建出AC自动机,套路地f[i][j]表示i时刻位于节点j的概率。

    构建转移矩阵,当i为某个子串结束节点时A[i][i]=1,否则A[i][j]+=p[j]。

    虽然事件总数无穷大,矩阵自乘50次就可以较为精确地得到结果了。

    注意AC自动机的节点是从0开始的。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
     5 typedef long double ld;
     6 using namespace std;
     7 
     8 const int N=110;
     9 char str[N];
    10 ld x,y,p[N];
    11 int n,len,m,nd,q[N],fail[N],ch[N][12],pos[N],b[N];
    12 
    13 struct Mat{
    14     ld a[N][N];
    15     ld* operator [](int x){ return a[x]; }
    16     Mat(){ memset(a,0,sizeof(a)); }
    17 }A;
    18 
    19 Mat mul(Mat &a,Mat &b){
    20     Mat c;
    21     rep(i,0,nd) rep(j,0,nd) rep(k,0,nd) c[i][k]+=a[i][j]*b[j][k];
    22     return c;
    23 }
    24 
    25 void ins(char s[],int id){
    26     int x=0;
    27     rep(i,1,len){
    28         int c=s[i]-'A'+1;
    29         if (!ch[x][c]) ch[x][c]=++nd;
    30         x=ch[x][c];
    31     }
    32     pos[id]=x; b[x]=1;
    33 }
    34 
    35 void getfail(){
    36     int st=0,ed=0;
    37     rep(i,1,m) if (ch[0][i]) q[++ed]=ch[0][i];
    38     while (st<ed){
    39         int x=q[++st];
    40         rep(i,1,m){
    41             if (ch[x][i]) fail[ch[x][i]]=ch[fail[x]][i],q[++ed]=ch[x][i];
    42                 else ch[x][i]=ch[fail[x]][i];
    43         }
    44     }
    45 }
    46 
    47 int main(){
    48     freopen("bzoj1444.in","r",stdin);
    49     freopen("bzoj1444.out","w",stdout);
    50     scanf("%d%d%d",&n,&len,&m);
    51     rep(i,1,m) scanf("%Lf%Lf",&x,&y),p[i]=x/y;
    52     rep(i,1,n) scanf("%s",str+1),ins(str,i);
    53     getfail();
    54     rep(i,0,nd){
    55         if (b[i]) { A[i][i]=1; continue; }
    56         rep(j,1,m) A[i][ch[i][j]]+=p[j];
    57     }
    58     rep(i,1,50) A=mul(A,A);
    59     rep(i,1,n) printf("%.2lf
    ",(double)A[0][pos[i]]);
    60     return 0;
    61 }
  • 相关阅读:
    Python操作Word:常用对象介绍
    Python入门教程 超详细1小时学会Python
    用几何画板画七边形的方法
    用ChemDraw画3D图的方法
    Chem 3D模型的参数值更改方法
    Chem 3D中怎么创建立体模型
    在几何画板中输入绝对值的方法
    怎么给几何画板文字加立体阴影效果
    几何画板放大和缩小的方法
    ChemDraw Pro和ChemBio3D Ultra有什么区别
  • 原文地址:https://www.cnblogs.com/HocRiser/p/9721890.html
Copyright © 2011-2022 走看看