poj Matrix Power Series 3233 (矩阵快速幂&二分)好题

来源:互联网 发布:20后网络数字用语 编辑:程序博客网 时间:2024/06/01 17:44
Matrix Power Series
Time Limit: 3000MS Memory Limit: 131072KTotal Submissions: 19132 Accepted: 8070

Description

Given a n × n matrix A and a positive integer k, find the sumS = A + A2 +A3 + … + Ak.

Input

The input contains exactly one test case. The first line of input contains three positive integersn (n ≤ 30), k (k ≤ 109) andm (m < 104). Then follown lines each containing n nonnegative integers below 32,768, givingA’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 40 11 1

Sample Output

1 22 3
思路:运用数学二分
对k进行二分,每次将规模减半,分k为奇偶两种情况,如当k = 6和k = 7时有:
      k = 6 有: S(6) = (1 + A^3) * (A + A^2 + A^3) = (1 + A^3) * S(3)。
      k = 7 有: S(7) = A + (A + A^4) * (A + A^2 + A^3) = A + (A + A^4) * S(3)。
#include<stdio.h>#include<string.h>#include<algorithm>#define INF 0x3f3f3f3f#define ll long long#define N 50using namespace std;struct mat{ll m[N][N];};int n,k,M;mat matadd(mat a,mat b)//矩阵相加 {int i,j;mat c;for(i=0;i<n;i++){for(j=0;j<n;j++){c.m[i][j]=(a.m[i][j]+b.m[i][j])%M;}}return c;}mat multi(mat a,mat b)//矩阵相乘 {int i,j,k;mat c;for(i=0;i<n;i++){for(j=0;j<n;j++){c.m[i][j]=0;for(k=0;k<n;k++){c.m[i][j]=(a.m[i][k]*b.m[k][j]+c.m[i][j])%M; }}}return c;}mat power(mat A,int k)//矩阵快速幂 {if(!k){memset(A.m,0,sizeof(A.m));for(int i=0;i<n;i++)A.m[i][i]=1;return A;}if(k==1)return A;mat c=power(A,k/2);if(k%2==0)return multi(c,c);elsereturn multi(multi(c,c),A);}mat matcal(mat A,int k)// 求S (k) = A + A2 + A3 + … + Ak{if(k==1)return A;mat b=power(A,(k+1)/2);mat c=matcal(A,k/2);if(k%2==0)return multi(matadd(power(A,0),b),c);// 如S(6) = (1 + A^3) * S(3)elsereturn matadd(A,multi(matadd(A,b),c));// 如S(7) = A + (A + A^4) * S(3)}int main(){int i,j;mat A;scanf("%d%d%d",&n,&k,&M);for(i=0;i<n;i++){for(j=0;j<n;j++){scanf("%lld",&A.m[i][j]);}}A=matcal(A,k);for(i=0;i<n;i++){for(j=0;j<n;j++){printf(j?" %lld":"%lld",A.m[i][j]);}printf("\n");}return 0;}

0 0
原创粉丝点击