POJ 3233 Matrix Power Series --二分求矩阵等比数列和

题意:求S(k) = A+A^2+...+A^k.

解法:二分即可。

if(k为奇)  S(k) = S(k-1)+A^k

else        S(k) = S(k/2)*(I+A^(k/2))

代码:

#include <iostream>

#include <cmath>

#include <cstdio>

#include <cstdlib>

#define SMod m

using namespace std;



int n,m,k;



struct Matrix

{

    int m[32][32];

    Matrix()

    {

        memset(m,0,sizeof(m));

        for(int i=1;i<=n;i++)

            m[i][i] = 1;

    }

};



Matrix Mul(Matrix a,Matrix b)

{

    Matrix res;

    int i,j,k;

    for(i=1;i<=n;i++)

    {

        for(j=1;j<=n;j++)

        {

            res.m[i][j] = 0;

            for(k=1;k<=n;k++)

                res.m[i][j] = (res.m[i][j]+(a.m[i][k]*b.m[k][j])%SMod + SMod)%SMod;

        }

    }

    return res;

}



Matrix add(Matrix a,Matrix b)

{

    Matrix res;

    memset(res.m,0,sizeof(res.m));

    int i,j;

    for(i=1;i<=n;i++)

        for(j=1;j<=n;j++)

            res.m[i][j] = (a.m[i][j]+b.m[i][j])%SMod;

    return res;

}



Matrix fastm(Matrix a,int b)

{

    Matrix res;

    while(b)

    {

        if(b&1LL)

            res = Mul(res,a);

        a = Mul(a,a);

        b >>= 1;

    }

    return res;

}



Matrix getsum(Matrix a,int b)

{

    Matrix A = a;

    Matrix I;

    if(b == 1)

        return A;

    if(b & 1)

        return add(getsum(a,b-1),fastm(a,b));

    else

        return Mul(getsum(a,b/2),add(I,fastm(a,b/2)));

}



int main()

{

    int i,j;

    while(scanf("%d%d%d",&n,&k,&m)!=EOF)

    {

        Matrix ans;

        for(i=1;i<=n;i++)

            for(j=1;j<=n;j++)

                scanf("%d",&ans.m[i][j]);

        ans = getsum(ans,k);

        for(i=1;i<=n;i++)

        {

            printf("%d",ans.m[i][1]%m);

            for(j=2;j<=n;j++)

                printf(" %d",ans.m[i][j]%m);

            puts("");

        }

    }

    return 0;

}
View Code

 

你可能感兴趣的:(Matrix)