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;
    }
    
  • 相关阅读:
    JAVA基础——编程练习(二)
    JAVA基础——面向对象三大特性:封装、继承、多态
    JVM内存
    50. Pow(x, n) (JAVA)
    47. Permutations II (JAVA)
    46. Permutations (JAVA)
    45. Jump Game II (JAVA)
    43. Multiply Strings (JAVA)
    42. Trapping Rain Water (JAVA)
    41. First Missing Positive (JAVA)
  • 原文地址:https://www.cnblogs.com/Skyminer/p/6500017.html
Copyright © 2011-2022 走看看