MisakaMKT

C++题解:Matrix Power Series ——矩阵套矩阵的矩阵加速

Matrix Power Series

r时间限制: 1 Sec 内存限制: 512 MB
题目描述
给定矩阵A,求矩阵S=A1+A2+……+A^k,输出矩阵,S矩阵中每个元都要模m。

数据范围: n (n ≤ 30) , k (k ≤ 109) ,m (m < 104)

输入
输入三个正整数n,k,m

输出
输出矩阵S mod m

样例输入

2 2 4
0 1
1 1
样例输出
1 2
2 3

这道题不多说,可以得出加速矩阵(E为单位矩阵,也就是形为[10...001...0............00...1]的矩阵,任何矩阵乘以这个单位矩阵还是原矩阵):
[AE0E]*[AE0E]=[A2E+A0E]
所以根据题目的要求,答案便是[AE0E]k+1的(1,2)
主要难点是矩阵套矩阵,详见代码:

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
      
#define N 35
#define P 5
#define LL long long
     
LL fuck,k,mod;
 
struct M {
    int n,m,c[N][N];
    M() { 
        n=m=fuck; 
        memset(c,0,sizeof(c)); 
    } 
    M operator * (const M& a) {
        M r;
        r.n=n;r.m=a.m;
        for(int i=1;i<=r.n;i++)
            for(int j=1;j<=r.m;j++)
                for(int k=1;k<=m;k++)
                    r.c[i][j]= ( r.c[i][j] + (c[i][k] * a.c[k][j] ) % mod) % mod;
        return r;
    }
    M operator + (const M& a) {
        M r;
        for(int i=1;i<=r.n;i++)
            for(int j=1;j<=r.m;j++)
                r.c[i][j]=(c[i][j]+a.c[i][j]) %mod;
        return r;   
    }
    M operator - (const M& a) {
        M r;
        for(int i=1;i<=r.n;i++)
            for(int j=1;j<=r.m;j++)
                r.c[i][j]=r.c[i][j]+(mod+c[i][j]-a.c[i][j]) %mod;
        return r;
    }
    void _read() {
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                scanf("%lld",&c[i][j]);
    }
    void pre() {
        n=m=fuck;
        for(int i=1;i<=fuck;i++)
            c[i][i]=1;
    }
    void _print() {
        for(int i=1;i<=n;i++) {
            for(int j=1;j<=m;j++) {
                if(j!=1) cout<<" ";
                cout<<c[i][j];
            }
            if(i!=n) puts("");
        }
        puts("");
    }
}fuckk;
 
struct Matrix {
    LL n,m;
    M c[P][P];
    Matrix() { 
        m=2,n=2;
        memset(c,0,sizeof(c)); 
    };
    Matrix operator * (const Matrix& a) {
        Matrix r;
        r.n=n;r.m=a.m;
        for(int i=1;i<=r.n;i++)
            for(int j=1;j<=r.m;j++)
                for(int k=1;k<=m;k++)
                    r.c[i][j]=r.c[i][j] + (c[i][k] * a.c[k][j] );
        return r;
    }
     
    Matrix pow(Matrix a, LL indexx) {
        Matrix sum;sum.n=sum.m=2;
        sum.c[1][1].pre();
        sum.c[2][2].pre();
        //a.c[1][2]._print();
        while(indexx>0) {
			if(indexx&1) sum=sum*a;
			/*sum.c[1][1]._print();
            sum.c[1][2]._print();
            sum.c[2][1]._print();
            sum.c[2][2]._print();*/
            a=a*a;
            //a.c[1][1]._print();
            indexx/=2;
        }
        return sum;
    }
    void sub() {
        c[1][2]=c[1][2]-fuckk;
    }
     
}ans;
  
int main() {
    cin>>fuck>>k>>mod;
    M a,b;
    a._read(); 
    b.pre();
    fuckk=b;
    ans.c[1][1]=a;
    ans.c[1][2]=ans.c[2][2]=b;
    //ans.test(ans);
    ans=ans.pow(ans,k+1);
    //ans.c[1][2]._print();
    ans.sub();
    ans.c[1][2]._print();
}

posted on   MisakaMKT  阅读(293)  评论(0编辑  收藏  举报

编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)

导航

统计信息

点击右上角即可分享
微信分享提示