zoukankan      html  css  js  c++  java
  • jsoi2009 有趣的游戏

    题目贴图:

    题解:

    AC自动机/Trie图+矩阵乘法。

    首先构建矩阵,因为有:

    f[ i ] = Σ f[ j ] * g[ j ][ i ]

    然后就搞成矩乘了。

    把邻接矩阵自乘足够多次就行了。

    代码:

    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define N 12
    int n,l,m,tot,tl[N];
    double g[N];
    char ch[N];
    struct Trie
    {
        int ch[N],fl,w;
    }tr[N*N];
    void trie_pic()
    {
        queue<int>q;
        for(int i=1;i<=m;i++)
            if(tr[0].ch[i])
                q.push(tr[0].ch[i]);
        while(!q.empty())
        {
            int u = q.front();
            q.pop();
            for(int i=1;i<=m;i++)
            {
                int &v = tr[u].ch[i];
                if(!v)
                {
                    v = tr[tr[u].fl].ch[i];
                    continue;
                }
                tr[v].fl = tr[tr[u].fl].ch[i];
                q.push(v);
            }
        }
    }
    struct mr
    {
        double s[N*N][N*N];
    }j0;
    void build()
    {
        for(int i=0;i<=tot;i++)
        {
            if(tr[i].w)
            {
                j0.s[i][i]=1.0;
            }else
            {
                for(int j=1;j<=m;j++)
                {
                    j0.s[tr[i].ch[j]][i]+=g[j];
                }
            }
        }
    }
    mr operator * (mr &a,mr &b)
    {
        mr c;
        for(int i=0;i<=tot;i++)
            for(int j=0;j<=tot;j++)
            {
                c.s[i][j]=0.0;
                for(int k=0;k<=tot;k++)
                    c.s[i][j]+=a.s[i][k]*b.s[k][j];
            }
        return c;
    }
    mr fast(mr &a,int b)
    {
        mr ret = a;
        b--;
        while(b)
        {
            if(b&1)ret=ret*a;
            a=a*a;
            b>>=1;
        }
        return ret;
    }
    double ans[N];
    int main()
    {
        scanf("%d%d%d",&n,&l,&m);
        for(int a,b,i=1;i<=m;i++)
        {
            scanf("%d%d",&a,&b);
            g[i] = (double)a/b;
        }
        for(int i=1;i<=n;i++)
        {
            scanf("%s",ch+1);
            int u = 0;
            for(int j=1;j<=l;j++)
            {
                int c = ch[j]-'A'+1;
                if(!tr[u].ch[c])tr[u].ch[c]=++tot;
                u=tr[u].ch[c];
            }
            tr[u].w=1;
            tl[i]=u;
        }
        trie_pic();
        build();
        mr ans=j0;
        for(int i=1;i<=100;i++)ans=ans*ans;
        for(int i=1;i<=n;i++)
            printf("%.2lf
    ",ans.s[tl[i]][0]);
        return 0;
    }
  • 相关阅读:
    laravel5.5事件广播系统
    laravel5.5队列
    mui框架 页面无法滚动解决方法
    js绑定事件和解绑事件
    自适应网页设计(Responsive Web Design)
    【总结】IE和Firefox的Javascript兼容性总结
    Javascript 多浏览器兼容性问题及解决方案
    js兼容性问题总结
    CSS3新增的选择器和属性
    CSS3新属性解释及用法
  • 原文地址:https://www.cnblogs.com/LiGuanlin1124/p/10013332.html
Copyright © 2011-2022 走看看