2020 BIT冬训-二分三分快速幂矩阵 I - Matrix Power Series POJ - 3233(矩阵快速幂,分治思想(吧))

Problem 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+A2+A3+…+Ak.
令Sk=A+A2+A3+…+AK,则Sk=(1+Ak/2)*(A1+A2+A3+…+AK/2)(+AK)(若k为偶数则不用加,若k为奇数则加上)。
即SK=(1+AK/2)*SK/2(+AK)(若k为偶数则不用加,若k为奇数则加上)(1为单位矩阵)。
其中左边的因子用快速幂求出来,右边的Sk/2使用递归计算得出即可。
最后还需要判断下k的奇偶性来决定是否加上AK
AC代码如下(大部分是借鉴这个的。因为一开始确实有点超过我的能力范围,我会再单独多敲几遍的qwq
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int n,k,mod; 
typedef struct Mar{
    int m[35][35];
    void Init(){//单位矩阵
        memset(m,0,sizeof(m));
        for(int i=0;i<35;i++)
            m[i][i]=1;
    }
}Martrix;
Martrix Add(Martrix a,Martrix b){//矩阵加法
    Martrix c;
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
            c.m[i][j]=(a.m[i][j]+b.m[i][j])%mod;
    return c;
}
Martrix Multi(Martrix a,Martrix b){//矩阵乘法
    Martrix c;
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++){
            c.m[i][j]=0;
            for(int k=0;k<n;k++)
                c.m[i][j]+=(a.m[i][k]*b.m[k][j])%mod;
            c.m[i][j]%=mod;
        }
    return c;
}
Martrix    Quick_mod(Martrix a,int k){//快速幂
    Martrix ans;
    ans.Init();
    while(k){
        if(k&1)
            ans=Multi(ans,a);
        k>>=1;
        a=Multi(a,a);
    }
    return ans;
}
Martrix Outans(Martrix a,int k){
    if(k==1)
        return a;
    Martrix ans;
    ans.Init();
    ans=Add(ans,Quick_mod(a,k>>1));
    ans=Multi(ans,Outans(a,k>>1));
    if(k&1)
        ans=Add(ans,Quick_mod(a,k));
    return ans;
}
int main(){
        scanf("%d%d%d",&n,&k,&mod);
        Martrix a;
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                scanf("%d",&a.m[i][j]);
        Martrix ans=Outans(a,k);
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++){
                printf("%d ",ans.m[i][j]);
                if(j==n-1)
                    printf("\n");
            }
}

 

 

 




posted @ 2021-02-17 15:06  mikku  阅读(37)  评论(0)    收藏  举报