POJ3233MatrixPowerSeries

来源:互联网 发布:淘宝宝贝图片尺寸单位 编辑:程序博客网 时间:2024/05/16 04:51

POJ3233 Matrix Power Series

题意:
i=1nAi (k<=109)

思路

大神Cai曾出过一道类似的,不过那个还更难;
框架就是二分加快速幂
对于i=1nAi我们可以将该式分解为A=i=1n/2Ai,观察到只需要将A式乘上一个Ab/2,那么就可以得到B=i=n/2+1nAi+b/2,原式=A+B;
如果n是个偶数,那么A+B就可以了,如果n是个奇数,那么可以换一个东西(迷)
A=i=1n/2Ai,B=A(n+1)/2,那么将A*B得到C=i=(b+1)/2+1nAi+(b+1)/2,那么原式还差一个A(n+1)/2,所以加上凑好项了:

i=1nAi=i=1n/2Ai+i=(b+1)/2+1nAi+(b+1)/2+A(n+1)/2=A+B+C

#include <cstdio>#include <cstring>#include <iostream>using namespace std;#define Rep(i,s,t)  for(int i=s;i<=t;i++)struct Mat{    int m[31][31];};Mat a,init;int n,k,MOD;Mat Mul(Mat A,Mat B){    Mat c;    memset(c.m,0,sizeof c.m);    Rep(i,1,n)  Rep(j,1,n)  Rep(k,1,n)        c.m[i][j]=(c.m[i][j]+A.m[i][k]*B.m[k][j])%MOD;    return c;}Mat Add(Mat A,Mat B){    Mat c;    memset(c.m,0,sizeof c.m);    Rep(i,1,n)  Rep(j,1,n)              c.m[i][j]=(A.m[i][j]+B.m[i][j])%MOD;    return c;}Mat pow(Mat A,int k){    Mat ans=A,p=A;    k--;    while(k)    {        if(k & 1)   ans=Mul(ans,p);        p=Mul(p,p);        k>>=1;    }    return ans;}Mat Sum(Mat A,int k){    if(k==1)    return a;    Mat C=Sum(A,k>>1);    if(k & 1)   {        Mat K=pow(A,(k>>1)+1);        C=Add(Mul(C,K),Add(C,K));       }    else {            Mat K=pow(A,k>>1);            C=Add(Mul(C,K),C);    }    return C;}int main(){    while(scanf("%d%d%d",&n,&k,&MOD)!=EOF)    {        memset(a.m,0,sizeof a.m);        Rep(i,1,n)  Rep(j,1,n)  {scanf("%d",&a.m[i][j]);init.m[i][j]=(i==j);}        a=Sum(a,k);        Rep(i,1,n)  {Rep(j,1,n-1)   printf("%d ",a.m[i][j]);printf("%d\n",a.m[i][n]);}    }    return 0;}
0 0
原创粉丝点击