POJ 3233 Matrix Power Series (矩陣快速冪+等比數列二分求和)
阿新 • • 發佈:2019-02-18
Matrix Power Series
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 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 |
題意:
求S = A + A2 + A3 +
… + Ak.%m
POINT:
等比數列二分求和:
(1)當時,
(2)當時,那麼有
(3)當時,那麼有
#include <iostream> #include <stdio.h> #include <string.h> using namespace std; #define ll long long int n,m; struct mx { int c[33][33]; }; mx chen(mx a,mx b) { mx ans; for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { ans.c[i][j]=0; for(int k=1;k<=n;k++) { (ans.c[i][j]+=a.c[i][k]*b.c[k][j])%=m; } } } return ans; } mx add(mx a,mx b) { for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { (a.c[i][j]+=b.c[i][j])%=m; } } return a; } mx mxqkm(mx base,int mi) { mx ans; for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { ans.c[i][j]=i==j; } } while(mi) { if(mi&1) ans=chen(ans,base); mi>>=1; base=chen(base,base); } return ans; } mx sum(mx A,int k) { if(k == 1) return A; mx t=sum(A,k/2); if(k&1) { mx cur=mxqkm(A,k/2+1); return add(t,add(chen(t,cur),cur)); } else { mx cur=mxqkm(A,k/2); return add(t,chen(cur,t)); } } int main() { int k; while(~scanf("%d %d %d",&n,&k,&m)) { mx a; for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { scanf("%d",&a.c[i][j]); a.c[i][j]%=m; } } a=sum(a,k); for(int i=1;i<=n;i++) { int p=0; for(int j=1;j<=n;j++) { if(!p) printf("%d",a.c[i][j]); else printf(" %d",a.c[i][j]); p++; } printf("\n"); } } }