POJ 3233 Matrix Power Series(矩阵等比数列求和)

题意就是一个等比数列求和的意思,只不过每一项都是矩阵

这里需要进行一下转移矩阵的构造,形成一个递推累加的效果:

设 B = (A,I;0,I)

则B^(k + 1) = (A^(k + 1),I + A + A^2 + A^3 + … + A^k;0,I)

原题可解,代码如下

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <string>
#include <vector>
#include <stack>
#include <set>
#include <map>
using namespace std;
const int MAXN = 80;
int n, k, m;
struct  Matrix
{
    __int64 a[MAXN][MAXN];
    int r;//行数
    int c;//列数
}org, ans;
void print()
{
    for (int i = 0;i < n;i++)
    {
        for (int j = 0;j < n;j++)
        {
            if (j) cout << " ";
            if (i != j) cout << ans.a[i][j + n];
            else cout << (ans.a[i][j + n] - 1 < 0 ? m - 1 : ans.a[i][j + n] - 1);
        }
        cout << endl;
    }
}

Matrix mul(Matrix mat1, Matrix mat2)
{
    Matrix res;
    res.c = mat2.c;
    res.r = mat1.r;
    memset(res.a, 0, sizeof(res.a));
    for (int i = 0;i < mat1.r;i++)
    {
        for (int j = 0;j < mat2.c;j++)
        {
            for (int k = 0;k < mat1.c;k++)
            {
                res.a[i][j] += mat1.a[i][k] * mat2.a[k][j];
                res.a[i][j] %= m;
            }
            res.a[i][j] %= m;
        }
    }
    return res;
}

void fmp()
{
    k++;
    while (k)
    {
        if (k & 1) ans = mul(ans, org);
        org = mul(org, org);
        k >>= 1;
    }
}

int main()
{
    while(cin>>n>>k>>m)
    {
        int i, j;
        memset(org.a, 0, sizeof(org.a));
        memset(ans.a, 0, sizeof(ans.a));
        for (i = 0;i<n;i++) {
            for (j = 0;j<n;j++)
                scanf("%d", &org.a[i][j]);
        }
        for (i = 0;i<n;i++) {
            org.a[i + n][i + n] = org.a[i][i + n] = 1;
            ans.a[i][i] = ans.a[i + n][i + n] = 1;
        }
        org.c = org.r = 2 * n;
        ans.c = ans.r = 2 * n;
        fmp();
        print();
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值