• BZOJ 1875 [SDOI2009]HH去散步 ——动态规划 矩阵乘法


    发现t非常大,所以大概就是快速幂一类的问题了,

    然后根据k^3logn算了算,发现k大约是边数的时候复杂度比较合适。

    发现比较麻烦的就是前驱的记录,所以直接把边看做点,不能走反向边,但是可以走重边,然后t--

    之后弄出状态转移矩阵递推即可。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
      
    #define F(i,j,k) for (int i=j;i<=k;++i)
    #define D(i,j,k) for (int i=j;i>=k;--i)
    #define ll long long
      
    const ll md=45989;
    int n,m,t,A,B;
      
    int h[150],to[150],ne[150],fr[150],en=0,ans;
    void add(int a,int b)
    {to[en]=b;ne[en]=h[a];fr[en]=a;h[a]=en++;}
      
    struct Matrix{
        ll x[125][125];
        void init(){memset(x,0,sizeof x);}
        Matrix operator * (Matrix y) {
            Matrix ret; ret.init();
            F(i,0,en-1) F(k,0,en-1)
            {
                F(j,0,en-1) ret.x[i][k]+=x[i][j]*y.x[j][k];
                ret.x[i][k]%=md;
            }
            return ret;
        }
    }a,b;
      
    int main()
    {
        memset(h,-1,sizeof h);
        scanf("%d%d%d%d%d",&n,&m,&t,&A,&B);t--;
        a.init(); b.init();
        F(i,1,m)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            add(a,b);add(b,a);
        }
        F(i,0,en-1)
        {
            int st=to[i];
            for (int j=h[st];j>=0;j=ne[j])
                if ((i^1)!=j)b.x[i][j]++;
        }
        for (int i=h[A];i>=0;i=ne[i])
            a.x[0][i]=1;
        while (t)
        {
            if (t&1) a=a*b;
            b=b*b;
            t>>=1;
        }
        F(i,0,en-1) if (to[i]==B) (ans+=a.x[0][i])%=md;
        printf("%d
    ",ans);
    }
    

      

  • 相关阅读:
    android选择时间攻略
    安卓通知的基本用法
    个人作业----软件工程实践总结
    第三次作业——《K米评测》
    第二次结对编程作业——毕设导师智能匹配
    原型设计与需求分析
    作品调研
    软件工程的实践项目课程的自我目标
    软件工程实践总结作业20161231
    K米测试
  • 原文地址:https://www.cnblogs.com/SfailSth/p/6486891.html
Copyright © 2020-2023  润新知