zoukankan      html  css  js  c++  java
  • POJ 3233 Matrix Power Series (矩阵快速幂)

    题目链接

    Description

    Given a n × n matrix A and a positive integer k, find the sum S = A + A^2 + A^3 + … + A^k.

    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

    分析:
    可以很简单的看出来,这是求矩阵快速幂的题,但是这里面还有一个问题就是它不仅仅是求出一个快速幂就行了,是一系列的快速幂求和,如果我们用普通的方法把每一个幂次求出来然后再相加的话,TLE.所以我们得想到一个解决的办法。

    我们令矩阵I是n×n得单位矩阵,
    将矩阵A得形式转换为

    则左下角得那个n阶矩阵即为所求,但是还要注意的一点就是前面还加上了一个单位矩阵,所以最后的答案还要把单位矩阵减去。

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    using namespace std;
    int n,k,m;
    struct matrix
    {
        int tu[100][100];
        matrix()
        {
            memset(tu,0,sizeof(tu));
        }
    } A,B;
    matrix mul(matrix &A,matrix &B)///定义矩阵的乘法
    {
        matrix C;
        for(int i=0; i<2*n; i++)
            for(int j=0; j<2*n; j++)
                for(int k=0; k<2*n; k++)
                {
                    C.tu[i][j]=(C.tu[i][j]+(A.tu[i][k]*B.tu[k][j]%m))%m;
                }
        return C;
    }
    
    matrix quick_mi(matrix A,int b)///求一个矩阵的A的b次方
    {
        matrix C;
        for(int i=0; i<2*n; i++)
            C.tu[i][i]=1;
        while(b)
        {
            if(b&1)
                C=mul(C,A);
            b>>=1;
            A=mul(A,A);
        }
        return C;
    }
    
    void solve()
    {
    }
    int main()
    {
        scanf("%d%d%d",&n,&k,&m);
        for(int i=0; i<n; i++)
        {
            for(int j=0; j<n; j++)
            {
                scanf("%d",&A.tu[i][j]);
                B.tu[i][j]=A.tu[i][j];
            }
            B.tu[n+i][i]=B.tu[n+i][n+i]=1;///把整个矩阵扩展到2*n维
        }
        B=quick_mi(B,k+1);///求出这个矩阵的k+1次矩阵
        for(int i=0; i<n; i++)
            for(int j=0; j<n; j++)
            {
                int a=B.tu[n+i][j]%m;///要求的是左下角的n阶矩阵
                if(i==j)
                    a=(a+m-1)%m;///还要减去单位矩阵
                printf("%d%c",a,j+1==n?'
    ':' ');
            }
        return 0;
    }
    
  • 相关阅读:
    字符串、组合练习
    national flag
    常用的Linux操作
    大数据概述
    LL(1)文法
    简单有穷自动机
    简单C语言文法
    词法分析
    编译原理 141
    综合练习
  • 原文地址:https://www.cnblogs.com/cmmdc/p/7256813.html
Copyright © 2011-2022 走看看