POJ 3233 Matrix Power Series (矩阵快速幂)

Matrix Power Series

Time Limit: 3000MS   Memory Limit: 131072K
Total Submissions: 11954   Accepted: 5105

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

Source

POJ Monthly--2007.06.03, Huang, Jinsong
 
  题意:给出一个n*n的矩阵,和一个正整数k,S=A+A^2+A^3+......+A^k;矩阵中的每一个元素对m取模
 
  当k=1的时候,f(1)=A;当k=2时 f(2)=A+A^2,当k=3时f(3)=A+A^2+A^3 = A+A*(A+A^2)=A+A*( f(2) );所以我们得出 f(k)=f(k-1)*A+A;
  
  然后我们就可以试着构建矩阵:| A 1 | *| f(k-1) | =| f(k) |,再进行矩阵快速幂就好啦。
                | 0 1 |   |    A    |   |   A  |
 
  
  
#include<algorithm>
#include<iostream>
#include<stdio.h>
using namespace std;

int n,m,k;
struct Matrix
{
    long long val[30][30];
};
Matrix operator*(const Matrix &a,const Matrix &b)
{
    int i,j,k;
    Matrix ans;
    for(i=0;i<n;i++)
        for(j=0;j<n;j++)
            ans.val[i][j]=0;
    for(i=0;i<n;i++)
    {
        for(j=0;j<n;j++)
        {
            for(k=0;k<n;k++)
            {
                ans.val[i][j]+=a.val[i][k]*b.val[k][j];
            }
            ans.val[i][j]%=m;
        }
    }
    return ans;
}
Matrix operator+(const Matrix &a,const Matrix &b)
{
    int i,j,k;
    Matrix ans;
    for(i=0;i<n;i++)
        for(j=0;j<n;j++)
            ans.val[i][j]=a.val[i][j]+b.val[i][j],ans.val[i][j]%=m;
    return ans;
}
struct Matrix_1
{
    Matrix num[2][2];
};
Matrix_1 operator*(const Matrix_1 &a,const Matrix_1 &b)
{
    int i,j,k;
    Matrix_1 ans;
    Matrix p;
    for(i=0;i<n;i++)
    {
        for(j=0;j<n;j++)
        {
            p.val[i][j]=0;
        }
    }
    ans.num[0][0]=ans.num[0][1]=ans.num[1][0]=ans.num[1][1]=p;
    for(i=0;i<2;i++)
    {
        for(j=0;j<2;j++)
        {
            for(k=0;k<2;k++)
            {
                ans.num[i][j]=ans.num[i][j]+a.num[i][k]*b.num[k][j];
            }
        }
    }
    return ans;
}
void solve(int b,Matrix f)
{
    Matrix p,q;
    Matrix_1 ans,a;
    int i,j,k;
    for(i=0;i<n;i++)
    {
        for(j=0;j<n;j++)
        {
            if(i==j)
                p.val[i][j]=1;//单位矩阵
            else
                p.val[i][j]=0;
            q.val[i][j]=0;//0矩阵
        }
    }
    ans.num[0][0]=ans.num[1][1]=p;
    ans.num[0][1]=ans.num[1][0]=q;
    a.num[0][0]=f;
    a.num[0][1]=a.num[1][1]=p;
    a.num[1][0]=q;
    while(b)
    {
        if(b&1) ans=ans*a;
        b>>=1;
        a=a*a;
    }
    f=ans.num[0][0]*f+ans.num[0][1]*f;
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
                printf("%lld ",f.val[i][j]%m);
        }
        printf("\n");
    }
}
int main()
{
    int i,j,k;
    Matrix p;
    cin>>n>>k>>m;
    for(i=0;i<n;i++)
    {
        for(j=0;j<n;j++)
        {
            scanf("%lld",&p.val[i][j]);
        }
    }
    solve(k-1,p);
}

猜你喜欢

转载自www.cnblogs.com/Ray-/p/10667040.html