矩阵快速幂计算hdu1575

矩阵快速幂计算和整数快速幂计算相同。在计算A^7时,7的二进制为111,从而A^7=A^(1+2+4)=A*A^2*A^4.而A^2可以由A*A得到,A^4可以由A^2*A^2得到。计算两个n阶方阵的乘积复杂度为O(n^3)。k的二进制大约有logk位,总的复杂度为O(n^3*logk).

#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<queue>
#include<iomanip>
#include<vector>
#include<string.h>
#include<algorithm>
using namespace std;
const int MOD = 9973;
class Matrix{
    int n;
    int M[12][12];
    Matrix Matrix::operator*(Matrix& X);  //矩阵乘法
public:
    void input(int i, int j, int m){ M[i][j] = m; }
    Matrix(int n);  //初始化
    int trSum();   //计算矩阵迹
    Matrix quickPower(int k);//矩阵快速幂
};
Matrix::Matrix(int n){
    this->n = n;
    int i, j;
    for (i = 1; i <= n; i++)
    for (j = 1; j <= n; j++)
        M[i][j] = (i == j ? 1 : 0);
}

Matrix Matrix::operator*(Matrix& X){
    Matrix res(n);
    int i, j, k, ans;
    for (i = 1; i <= n; i++)
    for (j = 1; j <= n; j++){
        ans = 0;
        for (k = 1; k <= n; k++)
            ans += M[i][k] * X.M[k][j];
        res.M[i][j] = ans%MOD;
    }
    res.n = n;
    return res;
}

int Matrix::trSum(){
    int res = 0, i;
    for (i = 1; i <= n; i++)
        res += M[i][i];
    return res%MOD;
}

Matrix Matrix::quickPower(int k){
    Matrix Y(n);
    Matrix X = *this;
    while (k){
        if (k & 1)
            Y = Y*X;
        k >>= 1;
        X = X*X;
    }
    return Y;
}

int main(){
    int i, j, T, k, n,ans;
    scanf("%d", &T);
    while (T--){
        scanf("%d%d", &n,&k);
        Matrix X(n);
        for (i = 1; i <= n;i++)
        for (j = 1; j <= n; j++){
            scanf("%d", &ans);
            X.input(i, j, ans);
        }
        X = X.quickPower(k);
        printf("%ld\n",X.trSum());
    }
    return 0;
}
时间: 2024-12-18 15:58:40

矩阵快速幂计算hdu1575的相关文章

快速幂计算(整数快速幂/矩阵快速幂)

库函数pow是用朴素算法对浮点型数据进行幂运算的,时间复杂度为o(n),计算比较大的数可能会超时和数据溢出: //*************快速幂计算**************************************** 朴素算法实现: ll get_pow(ll x, ll n)  //** (这里的n要求不小于0,如果n小于0则令n=-n,并且最终返回1.0/ans即可){    ll ans=1;    while(n--)    {        ans*=x%MAX;    

算法笔记--矩阵快速幂

写的不错的博客:http://www.cnblogs.com/yan-boy/archive/2012/11/29/2795294.html 优点:根据数列递推式快速计算数列an的值(当n很大时) 步骤:由数列递推式构造矩阵,然后用矩阵快速幂计算矩阵的幂. 构造矩阵:对于an =x*an-1 +y*an-2 ,可以构造矩阵为: [an ,an-1]=[an-1 ,an-2]*A A=[x 1 y 0]; 矩阵快速幂模板: #include<iostream> #include<cstri

uva 11651 - Krypton Number System(矩阵快速幂)

题目链接:uva 11651 - Krypton Number System 题目大意:给定进制base,和分数score,求在base进制下,有多少个数的值为score,要求不能有连续相同的数字以及前导0.计算一个数的值即为相邻两位数的平方差和. 解题思路:因为score很大,所以直接dp肯定超时,但是即使对于base=6的情况,每次新添一个数score最大增加25(0-5),所以用dp[i][j]预处理出base平方以内的总数,然后用矩阵快速幂计算. #include <cstdio> #

uva 10870(矩阵快速幂)

题意:计算f(n) f(n) = a1 f(n - 1) + a2 f(n - 2) + a3 f(n - 3) + - + ad f(n - d), for n > d. 题解:斐波那契的变形,把2个扩大成d个,然后加了a1-ad的参数,构造矩阵直接矩阵快速幂计算. #include <stdio.h> #include <string.h> const int N = 20; struct Mat { long long g[N][N]; }res, ori; long

TZOJ--5480: 孤衾易暖 // POJ--3735 Training little cats (矩阵快速幂)

5480: 孤衾易暖 时间限制(普通/Java):1000MS/3000MS     内存限制:65536KByte 描述 哇,好难,我要放弃了(扶我起来,我还能A 寒夜纵长,孤衾易暖,钟鼓渐清圆. 生活也许有些不如意的地方,但是没有什么是拥有一只猫不能解决的,我最喜欢苏格兰折耳猫. 现在我有n只小猫,我要训练这些猫去满足我奇奇怪怪的需求. 就是要让他们去得到鱼,这样他们才会快乐.刚开始他们是没有鱼的 我对这些猫有3种训练要求: 第一种要求为get x,意为让第x只猫咪得到一条: 第二种要求为e

矩阵快速幂(入门) 学习笔记hdu1005, hdu1575, hdu1757

矩阵快速幂是基于普通的快速幂的一种扩展,如果不知道的快速幂的请参见http://www.cnblogs.com/Howe-Young/p/4097277.html.二进制这个东西太神奇了,好多优秀的算法都跟他有关系,这里所说的矩阵快速幂就是把原来普通快速幂的数换成了矩阵而已,只不过重载了一下运算符*就可以了,也就是矩阵的乘法,  当然也可以写成函数,标题中的这三个题都是关于矩阵快速幂的基础题.拿来练习练习熟悉矩阵快速幂,然后再做比较难点的,其实矩阵快速幂比较难的是构造矩阵.下面还是那题目直接说话

hdu1575 Tr A(矩阵快速幂)

题目: Tr A Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3689    Accepted Submission(s): 2754 Problem Description A为一个方阵,则Tr A表示A的迹(就是主对角线上各项的和),现要求Tr(A^k)%9973. Input 数据的第一行是一个T,表示有T组数据. 每组数据的

矩阵快速幂专题(一)

最近闲来无事,准备集中精力刷一波数论与图论.矩阵快速幂是数论里面的重要组成部分,值得我好好学习一下.因为题目比较多,分析也比较多,所以将此专题分成几个部分.做完这一专题,可能会暂时转向图论部分,然后等我组合数学学得差不多了,再回过头来继续做数论题. 矩阵快速幂算法的核心思想是将问题建模转化为数学模型(有一些简单题目是裸的矩阵模型,但是大部分难题就是难在要构造矩阵,用矩阵方法解决问题),推倒递推式,构造计算矩阵,用快速幂的思想求解矩阵A的n次方取mod,从而得到矩阵里面你需要的数据. 矩阵快速幂问

HDU 2243 考研路茫茫――单词情结 ——(AC自动机+矩阵快速幂)

和前几天做的AC自动机类似. 思路简单但是代码200余行.. 假设solve_sub(i)表示长度为i的不含危险单词的总数. 最终答案为用总数(26^1+26^2+...+26^n)减去(solve_sub(1)+solve(2)+...+solve_sub(n)).前者构造f[i]=f[i-1]*26+26然后矩阵快速幂即可(当然也可以分治的方法).后者即构造出dp矩阵p,然后计算(p^1+p^2+...+p^n),对其分治即可. 代码如下: 1 #include <stdio.h> 2 #