poj3233 Matrix Power Series
Time Limit: 3000MS | Memory Limit: 131072K | |
Total Submissions: 18578 | Accepted: 7858 |
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
这题可以用矩阵快速幂做。列方程知道dp[i]=dp[i-1]+A[i],所以可以构造矩阵
【A^i,dp[i-1]】*B=【A^(i+1),dp[i]】
其中B=A E
E E
其中E是单位矩阵。
为了方便,可以使得【A^i,dp[i-1]】补成A^i dp[i-1]
0 1
这样就是求B^(k+1)次了
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
#define inf 99999999
#define pi acos(-1.0)
ll MOD;
struct matrix{
ll n,m,i;
ll data[80][80];
void init_danwei(){
for(i=0;i<n;i++){
data[i][i]=1;
}
}
}a;
matrix multi(matrix &a,matrix &b){
ll i,j,k;
matrix temp;
temp.n=a.n;
temp.m=b.m;
for(i=0;i<temp.n;i++){
for(j=0;j<temp.m;j++){
temp.data[i][j]=0;
}
}
for(i=0;i<a.n;i++){
for(k=0;k<a.m;k++){
if(a.data[i][k]>0){
for(j=0;j<b.m;j++){
temp.data[i][j]=(temp.data[i][j]+(a.data[i][k]*b.data[k][j])%MOD )%MOD;
}
}
}
}
return temp;
}
matrix fast_mod(matrix &a,ll n){
matrix ans;
ans.n=a.n;
ans.m=a.m;
memset(ans.data,0,sizeof(ans.data));
ans.init_danwei();
while(n>0){
if(n&1)ans=multi(ans,a);
a=multi(a,a);
n>>=1;
}
return ans;
}
int main()
{
ll n,m,i,j,k;
while(scanf("%lld%lld%lld",&n,&k,&MOD)!=EOF)
{
memset(a.data,0,sizeof(a.data ));
for(i=0;i<n;i++){
for(j=0;j<n;j++){
scanf("%lld",&a.data[i][j]);
}
}
a.n=a.m=2*n;
for(i=0;i<n;i++){
a.data[i][i+n]=a.data[i+n][i+n]=1;
}
matrix cnt;
cnt=fast_mod(a,k+1);
int c;
for(i=0;i<n;i++){
int flag=1;
for(j=0;j<n;j++){
if(i==j){
cnt.data[i][j+n]--;
}
if(flag){
flag=0;printf("%lld",(cnt.data[i][j+n]+MOD)%MOD );
}
else printf(" %lld",(cnt.data[i][j+n]+MOD)%MOD );
}
printf("\n");
}
}
return 0;
}