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

本文介绍了一种通过矩阵快速幂方法求解矩阵幂级数S=A+A^2+...+A^k的问题,其中A为n×n矩阵,k为正整数。通过构造特殊矩阵B,并利用矩阵乘法和快速幂技巧,有效地解决了大规模计算问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Matrix Power Series
Time Limit: 3000MS Memory Limit: 131072K
Total Submissions: 12008 Accepted: 5131

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

 

题意:给出矩阵A,求S = A + A2 + A3 + … + Ak

分析:把问题转化以加速,令

B = A  I         (这里的1是单位矩阵)

      0  I

则B^(k + 1) = A^(k + 1)      I + A + A2 + A3 + … + Ak  

                            0                          I           

可以先用矩阵快速幂求B^(k + 1),再求出S

 

AC代码:

#include <cstring>
#include <string>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cmath>
#include <vector>
#include <cstdlib>
#include <iostream>

using namespace std;
typedef struct node
{
    int m[65][65];
    void init()
    {
        memset(m,0,sizeof(m));
    }
}matrix;
matrix ans,b;
int n,k,m;
void init()
{
    ans.init();
    b.init();
    scanf("%d%d%d",&n,&k,&m);
    for(int i=0;i<n;i++)
    for(int j=0;j<n;j++)
    {
        scanf("%d",&b.m[i][j]);
        b.m[i][j]%=m;
    }
    for(int i=0;i<n;i++)
    {
        b.m[i][n+i]=b.m[n+i][n+i]=1;     //在矩阵b中添加单位矩阵
        ans.m[i][i]=ans.m[n+i][n+i]=1;   //初始化ans为单位矩阵
    }
}
matrix mul(matrix a,matrix b)
{
   matrix temp;
   temp.init();
   for(int i=0;i<n*2;i++)
   for(int j=0;j<n*2;j++)
   {
       for(int k=0;k<n*2;k++)
       temp.m[i][j]+=(a.m[i][k]*b.m[k][j])%m;
       temp.m[i][j]%=m;
   }
   return temp;
}
void solve()
{
    k++;
    while(k)
    {
        if(k&1)
        ans=mul(ans,b);
        b=mul(b,b);
        k>>=1;
    }
}
void Output()  //输出时要减单位矩阵
{
    for(int i=0;i<n;i++)
    {
    for(int j=0;j<n;j++)
    {
        if(i!=j) printf("%d ",ans.m[i][j+n]); 
        else printf("%d ",ans.m[i][j+n]-1);
    }
    printf("\n");
    }
}
int main()
{
   init();
   solve();
   Output();
   return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值