zoukankan      html  css  js  c++  java
  • bzoj 2553: [BeiJing2011]禁忌 AC自动机+矩阵乘法

    题目大意:

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

    题解:

    利用AC自动机的dp求出所有的转移
    然后将所有的转移储存到矩阵中,进行矩阵乘法即可

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    inline void read(int &x){
        x=0;char ch;bool flag = false;
        while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
        while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
    }
    const int maxn = 88;
    int maxc,n,m;
    int ch[maxn][26],nodecnt;
    bool danger[maxn];
    inline void insert(char *s){
        int len = strlen(s),nw = 0;
        for(int i=0;i<len;++i){
            int c = s[i] - 'a';
            if(ch[nw][c] == 0){
                ch[nw][c] = ++ nodecnt;
            }
            nw = ch[nw][c];
        }danger[nw] = true;
    }
    int fail[maxn],q[maxn];
    inline void build(){
        int l = 0,r = -1;
        for(int c=0;c<maxc;++c){
            if(ch[0][c]){
                fail[ch[0][c]] = 0;
                q[++r] = ch[0][c];
            }
        }
        while(l <= r){
            int u = q[l++];
            for(int c=0;c<maxc;++c){
                int t = ch[fail[u]][c];
                if(!ch[u][c]) ch[u][c] = t;
                else{
                    danger[ch[u][c]] |= danger[t];
                    fail[ch[u][c]] = t;
                    q[++r] = ch[u][c];
                }
            }
        }
    }
    struct Matrix{
        int n,m;
        long double s[maxn][maxn];
        void clear(int n = 0,int m = 0){
            this->n = n;this->m = m;
            memset(s,0,sizeof s);
        }
        Matrix friend operator * (const Matrix &a,const Matrix &b){
            Matrix c;c.clear(a.n,b.m);
            for(int i=0;i<c.n;++i){
                for(int j=0;j<c.m;++j){
                    for(int k=0;k<a.m;++k){
                        c.s[i][j] += a.s[i][k]*b.s[k][j];
                    }
                }
            }return c;
        }
    };
    Matrix ori,mul;
    inline Matrix qpow(Matrix x,int p){
        Matrix ret;ret.clear(x.m,x.m);
        for(int i=0;i<x.m;++i) ret.s[i][i] = 1;
        for(;p;p>>=1,x=x*x) if(p&1) ret=ret*x;
        return ret;
    }
    char s[22];
    int main(){
        read(n);read(m);read(maxc);
        for(int i=1;i<=n;++i){
            scanf("%s",s);
            insert(s);
        }build();
        ori.clear(1,nodecnt+2);ori.s[0][nodecnt+1] = 1.0;
        mul.clear(nodecnt+2,nodecnt+2);
        for(int i=0;i<=nodecnt;++i){
            for(int c=0;c<maxc;++c){
                if(danger[ch[i][c]]){
                    mul.s[0][i] += 1.0/maxc;
                    mul.s[nodecnt+1][i] += 1.0/maxc;
                }else{
                    mul.s[ch[i][c]][i] += 1.0/maxc;
                }
            }
        }mul.s[nodecnt+1][nodecnt+1] = 1.0;
        Matrix ans = ori*qpow(mul,m);
        printf("%.10lf",((double)ans.s[0][0]));
        getchar();getchar();
        return 0;
    }
    
  • 相关阅读:
    jenkins安装
    HTTP协议客户端是如何向服务器发送请求
    接口概念
    fiddler导出har格式转化成yml格式

    双硬盘双系统装错了记录
    chrome的版本和driver版本对应表
    monkey详解
    adb命令熟悉
    cookie、session、token
  • 原文地址:https://www.cnblogs.com/Skyminer/p/6500017.html
Copyright © 2011-2022 走看看