zoukankan      html  css  js  c++  java
  • Poj 3233 矩阵快速幂,暑假训练专题中的某一道题目,矩阵快速幂的模板

    题目链接  请猛戳~

    Description

    Given a n × n matrix A and a positive integer k, find the sum S = A + A2 + A3 + … + Ak.

    Input

    The input contains exactly one test case. The first line of input contains three positive integers n (n ≤ 30), k (k ≤ 109) and m (m < 104). Then follow n lines each containing n nonnegative integers below 32,768, giving A’s elements in row-major order.

    Output

    Output the elements of S modulo m in the same way as A is given.

    Sample Input

    2 2 4
    0 1
    1 1

    Sample Output

    1 2
    2 3

    结题思路:

    当k为偶数时,s(k)=(1+A^(k/2))*(A+A^2+…+A^(k/2))
    
     当k为奇数时,s(k)=A+(A+A^(k/2+1))*(A+A^2+…+A^(k/2))加以递归求解
    #include <iostream>
    #include <string.h>
    #include <cstdio>
    using namespace std;
    const int MAX = 32;
    struct Matrix{
        int v[MAX][MAX];
    };
    Matrix E;//定义单位矩阵 E
    int n,k,M;
    Matrix add(Matrix a,Matrix b){//矩阵加法运算
        Matrix c;
        for(int i = 1;i <= n;i++)
        for(int j = 1;j <= n;j++){
            c.v[i][j] = (a.v[i][j] + b.v[i][j]) % M;
        }
        return c;
    }
    Matrix mul(Matrix a,Matrix b){//矩阵乘法运算
        Matrix c;
        for(int i = 1;i <= n;i++)
        for(int j = 1;j <= n;j++){
            c.v[i][j] = 0;
            for(int k = 1;k <= n;k++)
            c.v[i][j] = (a.v[i][k] * b.v[k][j] + c.v[i][j]) % M;
        }
        return c;
    }
    Matrix pow(Matrix a,int k){//矩阵幂运算
        if(k == 0){
            memset(a.v,0,sizeof(a.v));
            for(int i = 1;i <= n;i++)
                a.v[i][i] = 1;
            return a;
        }else if(k == 1) return a;
        Matrix c = pow(a,k / 2);
         if(k & 1){
            return mul(a,mul(c,c));
        }else
            return mul(c,c);
    }
    Matrix sum(Matrix a,int k){ //连续升幂求和
        if(k == 1)return a;
        Matrix b = pow(a,(k + 1) / 2);
        Matrix c = sum(a,k / 2);
        if(k % 2){
            return add(a,mul(add(a,b),c));
        }else
            return mul(add(E,b),c);
    }
    void initE(){ //初始化单位矩阵E
        memset(E.v,0,sizeof(E.v));
        for(int i = 1;i <= n;i++) E.v[i][i] = 1;
    }
    void print(Matrix a){
        for(int i = 1;i <= n;i++){
            for(int j = 1;j <= n;j++)
            printf("%d ",a.v[i][j]);
            puts("");
        }
    }
    Matrix get(){
        Matrix a;
        for(int i = 1;i <= n;i++)
            for(int j = 1;j <= n;j++)scanf(" %d",&a.v[i][j]);
        return a;
    }
    int main()
    {
     
        while(~scanf("%d%d%d",&n,&k,&M)){
            initE();
            Matrix a = get();
            Matrix b = sum(a,k);
            print(b);
            }
        return 0;
    }
    额 继续努力吧 骚年~~~
  • 相关阅读:
    https://github.com/cykl/infoqscraper/
    C# 笔记
    json.org
    python html parse
    doxygen
    review board
    ruunlevel debian
    连接REDIS
    composer
    php需要注意的地方
  • 原文地址:https://www.cnblogs.com/jusonalien/p/4020573.html
Copyright © 2011-2022 走看看