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

Matrix Power Series

r时间限制: 1 Sec 内存限制: 512 MB
题目描述
给定矩阵A,求矩阵S=A^1+A^2+……+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为单位矩阵,也就是形为\(\begin{bmatrix}1&0&...&0\\0&1&...&0\\... &...&...&...\\0&0& ...&1\end{bmatrix}\)的矩阵,任何矩阵乘以这个单位矩阵还是原矩阵):
\(\begin{bmatrix} A &E \\ 0 & E \end{bmatrix}\)*\(\begin{bmatrix} A &E \\ 0 & E \end{bmatrix}\)=\(\begin{bmatrix} A^{2} &E+A \\ 0 & E \end{bmatrix}\)
所以根据题目的要求,答案便是\(\begin{bmatrix} A &E \\ 0 & E \end{bmatrix}^{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();
}

原文地址:https://www.cnblogs.com/MisakaMKT/p/10716541.html

时间: 2024-10-31 06:09:59

C++题解:Matrix Power Series ——矩阵套矩阵的矩阵加速的相关文章

矩阵十点【两】 poj 1575 Tr A poj 3233 Matrix Power Series

poj 1575  Tr A 主题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1575 题目大意:A为一个方阵,则Tr A表示A的迹(就是主对角线上各项的和),现要求Tr(A^k)%9973. 数据的第一行是一个T,表示有T组数据. 每组数据的第一行有n(2 <= n <= 10)和k(2 <= k < 10^9)两个数据.接下来有n行,每行有n个数据,每一个数据的范围是[0,9].表示方阵A的内容. 一个矩阵高速幂的裸题. 题解: #

Matrix Power Series(矩阵快速幂)

矩阵快速幂:http://www.cnblogs.com/kuangbin/archive/2012/08/17/2643347.html Matrix Power Series Time Limit: 3000MS   Memory Limit: 131072K Total Submissions: 16341   Accepted: 6966 Description Given a n × n matrix A and a positive integer k, find the sum S

POJ 3233 - Matrix Power Series ( 矩阵快速幂 + 二分)

POJ 3233 - Matrix Power Series ( 矩阵快速幂 + 二分) #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long LL; #define MAX_SIZE 30 #define CLR( a, b ) memset( a, b, sizeof(a) ) int MOD = 0; int n, k; st

POJ 3233 Matrix Power Series(矩阵+二分)

题目大意:求由矩阵 A构成的矩阵 S = A + A^2 + A^3 + - + A^k.k的取值范围是:10^9数据很大,应该二分. 对于一个k来说,s(k) = (1+A^(k/2)) *( A+A^2+--+A^(k/2)).如果k为奇数的话需要加上A^(k/2 + 1). 所以二分求和,复杂度就降下来了,当然还得用到矩阵快速幂. Matrix Power Series Time Limit: 3000MS   Memory Limit: 131072K Total Submissions

POJ 3233 Matrix Power Series(矩阵快速幂)

Default Matrix Power Series Time Limit: 3000MS Memory Limit: 131072K Total Submissions: 15553 Accepted: 6658 Description Given a n × n matrix A and a positive integer k, find the sum S = A + A2 + A3 + - + Ak. Input The input contains exactly one test

构造矩阵解决问题 【nyoj299 Matrix Power Series】

矩阵的又一个新用法,构造矩阵进行快速幂. 比如拿 nyoj299 Matrix Power Series 来说 给出这样一个递推式: S = A + A2 + A3 + - + Ak. 让你求s,A是一个矩阵,而k非常大.怎么办呢? 推理发现:Fn = A + A*F(n-1) 然后我们可以构造矩阵: (Fn ,1 ) =  (Fn-1 ,1) * (A,0.A,1) = (F1 , 1) * (A,0.A,1)^K-1 那么我们就可以用一个矩阵快速幂了. 下面是模板题目的代码: #includ

Poj 3233 Matrix Power Series(矩阵二分快速幂)

题目链接:http://poj.org/problem?id=3233 解题报告:输入一个边长为n的矩阵A,然后输入一个k,要你求A + A^2 + A^3 + A^4 + A^5.......A^k,然后结果的每个元素A[i][j] % m.(n <= 30,k < 10^9,m < 10^4) 要用到矩阵快速幂,但我认为最重要的其实还是相加的那个过程,因为k的范围是10^9,一个一个加肯定是不行的,我想了一个办法就是我以k = 8为例说明: ans = A + A^2 + A^3 +

poj 3233 Matrix Power Series(等比矩阵求和)

http://poj.org/problem?id=3233 ps转: 用二分方法求等比数列前n项和:即 原理: (1)若n==0 (2)若n%2==0     (3)若n%2==1 代码如下: LL sum(LL p,LL n) { if(n==0) return 1; if(n&1) return (1+pow(p,(n>>1)+1))*sum(p,n>>1); else return (1+pow(p,(n>>1)+1))*sum(p,(n-1)>&

构造矩阵解决这个问题 【nyoj299 Matrix Power Series】

矩阵的又一个新使用方法,构造矩阵进行高速幂. 比方拿 nyoj299 Matrix Power Series 来说 给出这样一个递推式: S = A + A2 + A3 + - + Ak. 让你求s.A是一个矩阵,而k很大. 怎么办呢? 推理发现:Fn = A + A*F(n-1) 然后我们能够构造矩阵: (Fn .1 ) =  (Fn-1 ,1) * (A.0. A,1) = (F1 , 1) * (A,0. A,1)^K-1 那么我们就能够用一个矩阵高速幂了. 以下是模板题目的代码: #in