您的位置:首页 > 其它

POJ 3233-Matrix Power Series(矩阵快速幂+二分求矩阵和)

2015-03-05 14:19 489 查看
Matrix Power Series
Time Limit:3000MS Memory Limit:131072KB 64bit IO Format:%I64d & %I64u
Submit Status Practice POJ
3233

Appoint description:
System Crawler (2015-02-28)

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,求A + A^2 + A^3 + … + A^k的结果(两个矩阵相加就是对应位置分别相加)。输出的数据mod m。

思路:这是一道典型的矩阵快速幂的问题。用到两次二分,相当经典。矩阵快速幂。首先我们知道 A^x 可以用矩阵快速幂求出来。其次可以对k进行二分,每次将规模减半,分k为奇偶两种情况,如当k = 10和k = 5时有:

k = 10 有: S(10) = ( A^1+A^2+A^3+A^4+ A^5 ) + A^5 * ( A^1+A^2+A^3+A^4+A^5 ) = S(5) + A^5 * S(5)
k = 5 有: S(5) = ( A^1+A^2 ) + A^3 + A^3 * ( A^1+A^2 ) = S(2) +
A^3 + A^3 * S(2)
k = 2 有 : S(2) = A^1 + A^2 = S(1) + A^1 * S(1)。

应用这个式子后,规模k减小了一半。我们二分求出后再递归地计算,即可得到原问题的答案。

#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
#include <set>
#include <map>
#include <queue>
using namespace std;
const int inf=0x3f3f3f3f;
int n,mod;
struct node
{
int mp[50][50];
}init,res;
struct node Mult(struct node x,struct node y)
{
struct node tmp;
int i,j,k;
for(i=0;i<n;i++)
for(j=0;j <n;j++){
tmp.mp[i][j]=0;
for(k=0;k<n;k++){
tmp.mp[i][j]=(tmp.mp[i][j]+x.mp[i][k]*y.mp[k][j])%mod;
}
}
return tmp;
};
struct node expo(struct node x,int k)
{
struct node tmp;
int i,j;
for(i=0;i<n;i++)
for(j=0;j<n;j++){
if(i==j)
tmp.mp[i][j]=1;
else
tmp.mp[i][j]=0;
}
while(k){
if(k&1) tmp=Mult(tmp,x);
x=Mult(x,x);
k>>=1;
}
return tmp;
};
struct node add(struct node x,struct node y)
{
struct node tmp;
int i,j;
for(i=0;i<n;i++)
for(j=0;j<n;j++){
tmp.mp[i][j]=(x.mp[i][j]+y.mp[i][j])%mod;
}
return tmp;
};
struct node sum(struct node x,int k)
{
struct node tmp,y;
if(k==1) return x;
tmp=sum(x,k/2);
if(k&1){
y=expo(x,k/2+1);
tmp=add(Mult(y,tmp),tmp);
return add(tmp,y);
}
else{
y=expo(x,k/2);
return add(Mult(y,tmp),tmp);
}
};
int main()
{
int m,k,i,j,x;
scanf("%d %d %d",&n,&k,&mod);
for(i=0;i<n;i++)
for(j=0;j<n;j++){
scanf("%d",&x);
init.mp[i][j]=x%mod;
}
res=sum(init,k);
for(i=0;i<n;i++){
for(j=0;j<n;j++){
if(j==n-1)
printf("%d\n",res.mp[i][j]);
else
printf("%d ",res.mp[i][j]);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: