• [BJWC2011]禁忌 AC 自动机 概率与期望


    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<string>
    #include<queue>
    #include<cstdlib>
    #include<iostream>
    using namespace std;
    void setIO(string a){
        freopen((a+".in").c_str(),"r",stdin);
    }
    #define db long double
    #define maxn 100000
    
    char arr[maxn];
    
    int sigma, nodes, n;
    struct matrix{
        long double mat[150][150];
    }unit;
    
    void init(matrix &a){
        for(int i=0;i<=n;++i)
            for(int j=0;j<=n;++j) a.mat[i][j]=0;
    }
    void get(matrix &a){
        init(a);
        for(int i=0;i<=n;++i) a.mat[i][i]=1;
    }
    matrix operator*(matrix a,matrix b){
        matrix c;
        init(c);
        for(int i=0;i<=n;++i)
            for(int j=0;j<=n;++j)
                for(int k=0;k<=n;++k) c.mat[i][j]+=a.mat[i][k]*b.mat[k][j];
        return c;
    }
    matrix operator^(matrix a,int p){
        matrix ans;
        get(ans);
        while(p){
            if(p&1) ans=ans*a;
            a=a*a;
            p>>=1;
        }
        return ans;
    }
    struct Automaton{
        int ch[maxn][30], fail[maxn], tag[maxn];
        #define idx str[i]-'a'
        void insert(char str[]){
            int cnt=strlen(str),j=0;
            for(int i=0;i<cnt;++i) {
                if(!ch[j][idx]) ch[j][idx]=++nodes;
                j=ch[j][idx];
            }
            tag[j]=true, n=nodes+1;
        }
    
        queue<int>Q;
        bool vis[maxn];
        void build(){
            for(int i=0;i<sigma;++i) if(ch[0][i]) Q.push(ch[0][i]);
            while(!Q.empty()){
                int u=Q.front();Q.pop();
                for(int i=0;i<sigma;++i){
                    int r=ch[u][i];
                    if(!r){ ch[u][i]=ch[fail[u]][i]; continue;}
                    Q.push(r), fail[r]=ch[fail[u]][i], tag[r]|=tag[fail[r]];
                }
            }
            init(unit);
            Q.push(0), vis[0]=true;
            long double tmp=(long double)1/sigma;
            while(!Q.empty()){
                int u=Q.front();Q.pop();
                for(int i=0;i<sigma;++i){
                    if(!vis[ch[u][i]]) vis[ch[u][i]]=true, Q.push(ch[u][i]);
                    if(tag[ch[u][i]])  unit.mat[u][0]+=tmp, unit.mat[u][n]+=tmp;
                    else unit.mat[u][ch[u][i]]+=tmp;
                }
                unit.mat[n][n]=1;
            }
        }
    }aho;
    int main(){
        //setIO("input");
        int m,len;
        scanf("%d%d%d",&m,&len,&sigma);
        for(int i=1;i<=m;++i) scanf("%s",arr), aho.insert(arr);
        aho.build();
        matrix g=unit^len;
        printf("%.10f",(double)g.mat[0][n]);
        return 0;
    }
    

      

    说实话还是有点不太理解.....

    Code:

  • 相关阅读:
    Linux nginx 安装 启动
    MySQL5.7版本sql_mode=only_full_group_by问题解决办法
    Tomcat配置Gizp 客户端使用okHttp3
    tomcat 验证码显示问题
    JProfiler 教程 使用说明
    mysql update 子查询作为条件
    reids等非关系数据库管理工具treesoft
    常用Linux 命令
    vue中计算属性的get与set方法
    Less和Sass相同与不同
  • 原文地址:https://www.cnblogs.com/guangheli/p/9912200.html
Copyright © 2020-2023  润新知