【poj3233Matrix Power Series】二分+矩阵乘法或矩阵套矩阵乘法
矩阵乘法啊啊啊233
POJ3233
Matrix Power Series
| Time Limit: 3000MS | Memory Limit: 131072K | |
| Total Submissions: 27042 | Accepted: 11027 |
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
这道题思维难度并不大,有两种方法实现
1.二分+矩阵乘法。
因为我们知道对于 x^(2*n) == x^n * ( 1 + x^n)
那么我们可以一直递归下去。
伪代码:
matrix getsum(int x)
{
if(x==1) return A;
if(x&1) return getsum(x-1)*A;
else return getsum(x/2) * ( A^(x/2) + 1 );
}
2.矩阵套矩阵。
如果我们不看这个A是一个矩阵的话,那么我们看这不就是一个矩阵乘法等比数列求和板题吗?是的,类同那种写法,只是在矩阵里面套的数字也是一个矩阵。
下面只给出二分法的代码:
#include<cstdio>
#include<iostream>
using namespace std;
int n,k,mod;
struct arr
{
int a[35][35];
};
arr A;
arr jzjf(arr A,arr B)
{
arr C;
for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) C.a[i][j] = 0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
C.a[i][j] = ( A.a[i][j] + B.a[i][j] )%mod;
}
}
return C;
}
arr dw;
arr jzcf(arr A,arr B)
{
arr C;
for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) C.a[i][j] = 0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
for(int k=1;k<=n;k++)
{
C.a[i][j] = (C.a[i][j] + A.a[i][k]*B.a[k][j]%mod)%mod;
}
}
}
return C;
}
arr jzksm(int kkk)
{
arr C; arr D;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(i==j) C.a[i][j] = 1;
else C.a[i][j] = 0;
}
}
D=A;
for(;kkk;kkk>>=1,D=jzcf(D,D))
if(kkk&1) C=jzcf(C,D);
return C;
}
arr getsum(int x)
{
if(x==1) return A;
if(x&1) return jzjf( jzksm(x) , getsum(x-1) );
else
{
arr aha = getsum(x/2);
return jzjf(jzcf(aha,jzksm(x/2)),aha);
}
}
int main()
{
scanf("%d%d%d",&n,&k,&mod);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
scanf("%d",&A.a[i][j]);
A.a[i][j] %= mod;
}
}
for(int i=1;i<=n;i++) dw.a[i][i] = 1;
arr ans = getsum(k);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
ans.a[i][j]=(ans.a[i][j]%mod+mod)%mod;
printf("%d ",ans.a[i][j]%mod);
}
puts("");
}
return 0;
}

浙公网安备 33010602011771号