zoukankan      html  css  js  c++  java
  • 1898: [Zjoi2005]Swamp 沼泽鳄鱼

    矩阵乘法。

    邻接矩阵用矩阵乘法可以得到最后的方案数

    食人鱼是周期性的移动可以用12个矩阵表示。12个矩阵乘在一起得到第13个矩阵。

    然后k/12的部分用第13个矩阵快速幂转移,再乘下剩余的矩阵。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define LL long long 
    using namespace std;
    const int maxn = 50 + 10;
    const int mod = 10000;
    
    int n,m,p1,p2,k,nf;
    int t[maxn],q[maxn][maxn];
    
    struct Matrix {
        int a[maxn][maxn];
        
        int* operator [] (int x) {
            return a[x];
        }
        
        Matrix operator * (Matrix b) {
            Matrix res;
            for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
            for(int k=1;k<=n;k++)
                res[i][k]=(res[i][k]+a[i][j]*b[j][k])%mod;
            return res;
        }
        
        Matrix operator ^ (int e) {
            Matrix res,tmp=*this;
            res.init();
            while(e) {
                if(e&1) res=res*tmp;
                tmp=tmp*tmp;
                e>>=1;
            }
            return res;
        }
        
        void init() {
            memset(a,0,sizeof(a));
            for(int i=1;i<=n;i++) 
                a[i][i]=1;
        }
        
        Matrix() {
            memset(a,0,sizeof(a));    
        }
    }a[15],b,f;
    
    void build() {
        scanf("%d%d%d%d%d",&n,&m,&p1,&p2,&k);
        p1++; p2++;
        for(int i=1,u,v;i<=m;i++) {
            scanf("%d%d",&u,&v);
            u++; v++;
            b[u][v]=b[v][u]=1;
        }                                                                                   
                                                                
        scanf("%d",&nf);
        for(int i=1;i<=nf;i++) {
            scanf("%d",&t[i]);
            for(int j=0;j<t[i];j++) {
                scanf("%d",&q[i][j]);
                q[i][j]++;    
            }
        }
        
        for(int i=1;i<=12;i++) {
            a[i]=b;        
            for(int j=1,v;j<=nf;j++) {
                v=q[j][i%t[j]];
                for(int k=1;k<=n;k++) a[i][k][v]=0;
            }
        }
        
        b.init();
        for(int i=1;i<=12;i++) b=b*a[i];
        f.init();
         f=f*(b^(k/12));
            
        for(int i=1;i<=(k%12);i++) f=f*a[i];    
        printf("%d
    ",f[p1][p2]);
    }
    
    int main() {
        build();
        return 0;    
    }
  • 相关阅读:
    App测试总脚本1.30.py
    adb安装中的platform-tools文件的生成问题
    App测试总脚本1.20
    App测试总脚本1.10(使用了列表推导式)
    APP网络测试要点和弱网模拟
    算法1—冒泡排序
    三次握手和四次挥手
    测试基础总结
    四道题设计用例
    使用复杂条件下的if选择结构
  • 原文地址:https://www.cnblogs.com/invoid/p/5676793.html
Copyright © 2011-2022 走看看