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.
思路 A1+A2+A3+A4+A5+A6= A1+A2+A3 + A3(A1+A2+A3)
= (A1+A2+A3) *( A3+I) // I 是单位矩阵;
=( A1*(A1+I)+A3) * (A3+ I );
采用分治的思想,不断二分……
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<set>
#include<queue>
#include<map>
#include<vector>
using namespace std;
int k,n,mod;
struct node{
int w[40][40];
void init(){
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
scanf("%d",&w[i][j]);
}
void prf(){
for(int i=0;i<n;i++){
for(int j=0;j<n-1;j++) printf("%d ",w[i][j]);
printf("%d\n",w[i][n-1]);
}
}
node operator * (const node &b) const{
node cur;
memset(cur.w,0,sizeof(cur.w));
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
for(int k=0;k<n;k++){
cur.w[i][j]=(cur.w[i][j]+(w[i][k]*b.w[k][j])%mod)%mod;
}
}
}
return cur;
}
node operator + (const node &b) const{
node cur ;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++) cur.w[i][j]=(w[i][j]+b.w[i][j])%mod;
return cur;
}
};
node a,ans,I,tp;
node check(int x){
node cur=I,p=a;
while(x){
if(x&1) cur=cur*p;
p=p*p;
x>>=1;
}
return cur;
}
void dfs(int num){
if(num==1) return;
dfs(num/2);
tp=check(num/2);
ans=ans*(tp+I);
if(num&1){
tp=check(num);
ans=ans+tp;
}
}
int main()
{
// freopen("in.in","r",stdin);
memset(I.w,0,sizeof(I.w));
while(~scanf("%d%d%d",&n,&k,&mod)){
a.init();
ans=a;
for(int i=0;i<n;i++) I.w[i][i]=1;
dfs(k);
ans.prf();
}
return 0;
}