关闭

POJ 3233 矩阵运算,等比数列二分求和,矩阵

108人阅读 评论(0) 收藏 举报
分类:
#include"iostream"
#include"stdio.h"
#include"string.h"
using namespace std;
struct Mat{
    int res[45][45];
    Mat(){memset(res,0,sizeof(res));}
}I;
int n,m,k;
Mat mut(Mat a,Mat b) //矩阵乘法
{
    Mat c;
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
    {
        for(int k=0;k<n;k++)
            c.res[i][j]+=a.res[i][k]*b.res[k][j];
        c.res[i][j]%=m;
    }
    return c;
}
Mat add(Mat a,Mat b)         //矩阵加减
{
    Mat c;
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            c.res[i][j]=a.res[i][j]+b.res[i][j];
            c.res[i][j]%=m;
        }

    }
    return c;
}

Mat pow(Mat a,int cnt)
{
    Mat E=I,p=a;
    while(cnt)
    {
        if(cnt%2)           
        {
            E=mut(E,p);                    //任何矩阵 矩阵都是保持不变的
            cnt--;
        }
        cnt/=2;
        p=mut(p,p);
    }
    return E;
}

Mat sum(Mat a,int cnt)  //等比数列二分求和
{
    if(cnt==1) return a;
    Mat t=sum(a,cnt/2);
    if(cnt%2)
    {
        Mat cur=pow(a,cnt/2+1);
        t=add(t,mut(t,cur));
        t=add(cur,t);
    }
    else
    {
        Mat cur=pow(a,cnt/2);
        t=add(t,mut(t,cur));
    }
    return t;
}

void print(Mat a)
{
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        cout<<a.res[i][j]<<" ";
        cout<<endl;
    }
}



int main()
{
    while(cin>>n>>k>>m)
    {
        Mat a;
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
        {
            scanf("%d",&a.res[i][j]);
            a.res[i][j]%=m;           //一定要有
            if(i==j) I.res[i][j]=1;else I.res[i][j]=0;
        }
        Mat ans=sum(a,k);
        print(ans);
    }
}

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:34487次
    • 积分:2751
    • 等级:
    • 排名:第13548名
    • 原创:249篇
    • 转载:20篇
    • 译文:0篇
    • 评论:0条