• bzoj2553【beijing2011】禁忌


    题意:http://www.lydsy.com/JudgeOnline/problem.php?id=2553

    sol  :puts("nan"); (逃~

       ac自动机+矩阵快速幂

       先将所有的串放到ac自动机上,贪心匹配,对一个包含禁忌串的节点划分出一段

       设f[i][j]表示走了i步到达AC自动机上的j节点的概率

       转移方程为f[i+1][k]=f[i][j]/alphabet

       由于i较大,但是每一步的转移是一样的,所以可以用矩阵快速幂优化

       P.S.喜sang闻xin乐bing见kuang的出题人卡精度QAQ,需要开long double

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int Mx=110;
    struct Node { int l,r; long double f[Mx][Mx]; } str,final;  
    int n,m,cnt,len,num,ch[Mx][26],fail[Mx],q[Mx],jud[Mx];  
    char s[Mx]; 
    void build_trie()
    {  
        int x=0;  
        for(int i=1;i<=m;i++)
        {  
            if(!ch[x][s[i]-'a']) ch[x][s[i]-'a']=++cnt;
            x=ch[x][s[i]-'a'];
            if(jud[x]) break;
        }  
        jud[x]=1; 
    }  
    void get_fail()
    {  
        int h=0,t=1;q[h]=0;  
        while(h!=t)
        {  
            int now=q[h++]; if(h>Mx) h=0; 
            for(int i=0;i<num;i++)
                if(ch[now][i])
                {  
                    int x=ch[now][i],y=fail[now];
                    while(y&&(!ch[y][i])) y=fail[y]; 
                    if(ch[y][i]!=x) fail[x]=ch[y][i];
                    else fail[x]=0;
                    q[t++]=x; if(t>Mx) t=0;
                }
                else ch[now][i]=ch[fail[now]][i];  
        }  
        str.f[cnt+1][cnt+1]=1;
    }
    Node mul(Node x,Node y)
    {  
        Node tmp;tmp.l=x.l;tmp.r=y.r;
        memset(tmp.f,0,sizeof(tmp.f));
        for(int k=0;k<x.r;k++)  
            for(int i=0;i<x.l;i++)  
                for(int j=0;j<y.r;j++)  
                    tmp.f[i][j]+=x.f[i][k]*y.f[k][j];  
        return tmp; 
    }  
    void build()
    {
        get_fail();
        long double tmp=(long double) 1/num;  
        for(int i=0;i<=cnt;i++) 
            if(!jud[i])  
                for(int j=0;j<num;j++)
                    if(jud[ch[i][j]]) str.f[i][cnt+1]+=tmp,str.f[i][0]+=tmp;  
                    else str.f[i][ch[i][j]]+=tmp;  
        str.f[cnt+1][cnt+1]=1;
    }  
    void dfs(int x)
    {  
        if(jud[x])
            for(int i=0;i<num;i++) ch[x][i]=0;  
        else
            for(int i=0;i<num;i++)
                if(ch[x][i]) dfs(ch[x][i]);  
    }
    void pre()
    {
        scanf("%d%d%d",&n,&len,&num);  
        for (int i=1;i<=n;i++)
        {  
            scanf("%s",s+1); m=strlen(s+1);  
            build_trie();  
        }   
        dfs(0);
        str.l=str.r=cnt+2;  
        final.l=1,final.r=cnt+2,final.f[0][0]=1;
    }
    int main()
    {  
        pre();
        build();  
        for( ;len;len>>=1,str=mul(str,str)) if(len&1) final=mul(final,str);  
        printf("%.9lf",(double) final.f[0][cnt+1]);  
    }
  • 相关阅读:
    vsCode 使用 PHP Intelephense插件函数跳转跟踪
    acme.sh 生成证书一直卡在Getting domain auth token for each domain
    用命令行执行php脚本输出乱码
    js检测是否是手机平台
    个人知识结构索引
    离线环境下安装ansible,借助有网环境下pip工具
    zabbix之微信告警(python版):微信个人报警,微信企业号告警脚本
    使用ansible结合FTP部署zabbix_agent
    datax的可视化-datax-web
    Finereport决策报表
  • 原文地址:https://www.cnblogs.com/xiaoxubi/p/6480614.html
Copyright © 2020-2023  润新知