• HDU 5607 graph 矩阵快速幂 + 快速幂


    这道题得到了学长的助攻,其实就是一个马尔科夫链,算出一步转移矩阵进行矩阵快速幂就行了,无奈手残

    这是我第一回写矩阵快速幂,写的各种毛病,等到调完了已经8点44了,交了一发,返回PE,(发现是少了换行)再想交的时候已经开始hack了

    真是TMD。。。。。。。,然后rejudge完了之后再HDOJ上瞬间AC,真是。。。狗了,只能是自己手残

    手残,手残,手残(重要的事情说三遍)

    思路 :(杭电官方题解,我就不班门弄斧了。。QAQ)

    考虑dpdp,用f_{t,x}ft,x​​表示第tt秒在xx的概率,初始时f_{0,u}=1f0,u​​=1.

    f_{t+1,y}=sum_{x,x->y}{frac{f_{t,x}}{Out_x}},Out_xft+1,y​​=x,x>y​​Outx​​ft,x​​​​,Outx​​表示xx的出度.

    因为tt很大,而且发现每次的转移都是相同的,所以直接矩乘就好了.

    复杂度是O(QN^3log t)O(QN3​​logt).

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<cmath>
    #include<cstdlib>
    #include<vector>
    #include<queue>
    using namespace std;
    typedef long long LL;
    const int maxn=50+5;
    const LL mod=1e9+7;
    vector<int>g[maxn];
    int n,m;
    LL xx[maxn][maxn],yy[maxn][maxn];
    struct mat
    {
        LL x[maxn][maxn],y[maxn][maxn];
    } o,res;
    mat mul(mat a,mat b)
    {
        mat temp;
        for(int i=1; i<=n; ++i)
            for(int j=1; j<=n; ++j)
            {
                temp.x[i][j]=0;
                temp.y[i][j]=1;
                for(int k=1; k<=n; ++k)
                {
                    LL t1=a.x[i][k]*b.x[k][j]%mod;
                    LL t2=a.y[i][k]*b.y[k][j]%mod;
                    temp.x[i][j]=(temp.x[i][j]*t2%mod+temp.y[i][j]*t1%mod)%mod;
                    temp.y[i][j]=(temp.y[i][j]*t2)%mod;
                }
            }
        return temp;
    }
    void cal(int c)
    {
        for(int i=1; i<=n; ++i)
            for(int j=1; j<=n; ++j)
            {
                o.x[i][j]=xx[i][j];
                o.y[i][j]=yy[i][j];
                res.x[i][j]=0,res.y[i][j]=1;
            }
        for(int i=1; i<=n; ++i)
            res.x[i][i]=1;
        while(c)
        {
            if(c&1)
                res=mul(res,o);
            c>>=1;
            o=mul(o,o);
        }
    }
    LL getans(LL x,LL y)
    {
        int c=1e9+5;
        LL r=1;
        while(c)
        {
            if(c&1)
                r=(r*y)%mod;
            c>>=1;
            y=(y*y)%mod;
        }
        r=(x%mod*r%mod);
        return r;
    }
    int main()
    {
        while(~scanf("%d%d",&n,&m))
        {
            memset(xx,0,sizeof(xx));
            for(int i=1; i<=n; i++)
                for(int j=1; j<=n; j++)
                    yy[i][j]=1;
            for(int i=1; i<=n; ++i)
                g[i].clear();
            for(int i=0; i<m; ++i)
            {
                int u,v;
                scanf("%d%d",&u,&v);
                g[u].push_back(v);
            }
            for(int i=1; i<=n; ++i)
            {
                for(int j=0; j<g[i].size(); ++j)
                    xx[i][g[i][j]]=1,yy[i][g[i][j]]=g[i].size();
            }
            int q;
            scanf("%d",&q);
            while(q--)
            {
                int u,k;
                scanf("%d%d",&u,&k);
                cal(k);
                for(int i=1; i<=n; i++)
                    printf("%I64d ",getans(res.x[u][i],res.y[u][i]));
                printf("
    ");
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Java 8新特性探究(九)跟OOM:Permgen说再见吧
    Java 堆内存(Heap)[转]
    hashmap源码
    Java8学习笔记----Lambda表达式 (转)
    双重检查锁定与延迟初始化(转自infoq)
    kvm的live-snapshot
    8.25考试总结
    CF1151FSonya and Informatics
    CF1151div2(Round 553)
    BZOJ3728 PA2014Final Zarowki
  • 原文地址:https://www.cnblogs.com/shuguangzw/p/5095334.html
Copyright © 2020-2023  润新知