zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    .net 使用 swagger 操作
    oracle 基础
    关于webapi跨域问题的一些坑坑
    sqlHelper
    微博数据接入开发
    mvc后台上传
    sql server 报错处理
    asp.net 微信开发(二)
    收集一些关于OI/ACM的奇怪的东西……
    LeetCode 229 Majority Element II
  • 原文地址:https://www.cnblogs.com/pach/p/5986194.html
Copyright © 2011-2022 走看看