• POJ 3233 Matrix Power Series 矩阵快速幂+二分求和


    矩阵快速幂,请参照模板 http://www.cnblogs.com/pach/p/5978475.html

    直接sum=A+A2+A3...+Ak这样累加肯定会超时,但是

    sum=A+A2+...+Ak/2+A(k/2)*(A+A2+...+Ak/2)    k为偶数时;

    sum=A+A2+...+A(k-1)/2+A((k-1)/2)*(A+A2+...+A(k-1)/2)+Ak    k为奇数时。

    然后递归二分求和

    PS:刚开始mat定义的是__int64,于是贡献了n次TLE。。。

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    using namespace std;
    
    int n,m;
    const int N=55;
    
    struct Mat
    {
        int mat[N][N];
    };
    Mat Multiply(Mat a, Mat b)
    {
        Mat c;
        memset(c.mat, 0, sizeof(c.mat));
        for(int k = 0; k < n; ++k)
            for(int i = 0; i < n; ++i)
                if(a.mat[i][k])
                    for(int j = 0; j < n; ++j)
                        if(b.mat[k][j])
                            c.mat[i][j] = (c.mat[i][j] +a.mat[i][k] * b.mat[k][j])%m;
        return c;
    }
    Mat QuickPower(Mat a, int k)
    {
        Mat c;
        memset(c.mat,0,sizeof(c.mat));
        for(int i = 0; i < n; ++i)
            c.mat[i][i]=1;
        for(; k; k >>= 1)
        {
            if(k&1) c = Multiply(c,a);
            a = Multiply(a,a);
        }
        return c;
    }
    Mat Add(Mat a,Mat b)
    {
        for(int i=0; i<n; i++)
            for(int j=0; j<n; j++)
                a.mat[i][j]=(a.mat[i][j]+b.mat[i][j])%m;
        return a;
    }
    Mat Solve(Mat a,int k)
    {
        if(k==1)
            return a;
        Mat e,ret;
        memset(e.mat,0,sizeof(e.mat));
        for(int i=0; i<n; i++)
            e.mat[i][i]=1;
        ret=Multiply(Add(e,QuickPower(a,k>>1)),Solve(a,k>>1));
        if(k%2)
            return Add(ret,QuickPower(a,k));
        return ret;
    }
    int main()
    {
        //freopen("in.txt","r",stdin);
        int k;
        scanf("%d%d%d",&n,&k,&m);
        Mat a;
        for(int i=0; i<n; i++)
            for(int j=0; j<n; j++)
                scanf("%d",&a.mat[i][j]);
        Mat ans=Solve(a,k);
        for(int i=0; i<n; i++)
        {
            for(int j=0; j<n-1; j++)
                printf("%d ",ans.mat[i][j]);
            printf("%d
    ",ans.mat[i][n-1]);
        }
        return 0;
    }
  • 相关阅读:
    卤菜技巧
    JS实现延迟
    软件项目版本号的命名规则及格式
    EF复合主键
    验证码和验证控件
    还原数据库,数据库提示正在还原中的处理办法
    更新汇总行
    centOS7挂在windows移动硬盘方法
    关于this、Echarts中的data
    SQLServer 查看SQL语句的执行时间
  • 原文地址:https://www.cnblogs.com/pach/p/5986194.html
Copyright © 2020-2023  润新知