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

点击打开链接

Matrix Power Series

Time Limit: 3000MS   Memory Limit: 131072K
Total Submissions: 19189   Accepted: 8099

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 case. The first line of input contains three positive integers n (n ≤ 30), k (k ≤ 109) and m (m < 104). Then follow n lines each containing n nonnegative
integers below 32,768, giving A’s elements in row-major order.

Output

Output the elements of S modulo m in the same way as A is given.

Sample Input

2 2 4
0 1
1 1

Sample Output

1 2
2 3

题目大意:

给定一个 n*n  的矩阵和一个整数 k,,要求的是S =  A + A2 + A3 +
… + Ak.

出的是 S%Mod

解题思路:

首先这是一个矩阵的快速幂,将Ak 用矩阵的快速幂求解出来(可以套模板),

可以推出以下结论

Sk = A + A2 + A3 + … + Ak   

    =(1+Ak/2)*(A + A2 + A3 + … + Ak/2  )+(Ak )

    =(1+Ak/2)*(Sk/2 )+(Ak )

然后可以递归啦,首先计算的是(1+Ak/2),

这里的 1 不仅是 1 它是一个单位矩阵,然后递归一下,最后判断一下奇偶性

要是偶数的时候就不用+(Ak ),要是奇数的话就+(Ak ),具体详见代码:

#include <iostream>
#include <cstring>
using namespace std;
typedef struct Mar
{
    int m[40][40];
    void Init()///初始化为单位矩阵
    {
        memset(m, 0, sizeof(m));
        for(int i=0; i<40; i++)
            m[i][i] = 1;
    }
} Martrix;

int n, Mod;

Martrix Add(Martrix a, Martrix b)///矩阵加法
{
    Martrix c;
    for(int i=0; i<n; i++)
        for(int j=0; j<n; j++)
            c.m[i][j] = (a.m[i][j] + b.m[i][j]) % Mod;///一定要模 Mod
    return c;
}
Martrix Multi(Martrix a, Martrix b)///矩阵乘法
{
    Martrix c;
    for(int i=0; i<n; i++)
    {
        for(int j=0; j<n; j++)
        {
            c.m[i][j] = 0;
            for(int k=0; k<n; k++)
                c.m[i][j] += (a.m[i][k]*b.m[k][j])%Mod;///一定要模 Mod,将数值减小
            c.m[i][j] %= Mod;
        }
    }
    return c;
}
Martrix quick_mod(Martrix a, int b)///矩阵的快速幂
{
    Martrix ans;
    ans.Init();
    while(b)
    {
        if(b & 1)
            ans = Multi(ans, a);
        b>>=1;///二分
        a = Multi(a, a);
    }
    return ans;
}
Martrix Get_sum(Martrix a, int k)///递归
{
    if(k == 1)
        return a;
    Martrix ans;
    ans.Init();
    ans = Add(ans, quick_mod(a, k>>1));///1+A^(k/2)
    ans = Multi(ans,Get_sum(a,k>>1));///剩下的
    if(k & 1)///判断奇偶性
        ans = Add(ans,quick_mod(a,k));
    return ans;
}
int main()
{
    int k;
    while(cin>>n>>k>>Mod)
    {
        Martrix a;
        for(int i=0; i<n; i++)
            for(int j=0; j<n; j++)
                cin>>a.m[i][j];
        Martrix ans = Get_sum(a,k);
        for(int i=0; i<n; i++)
        {
            for(int j=0; j<n-1; j++)
                cout<<ans.m[i][j]<<" ";
            cout<<ans.m[i][n-1]<<endl;
        }
    }
    return 0;
}
时间: 2024-08-01 21:27:41

PKU 3233 Matrix Power Series(矩阵快速幂 二分)的相关文章

poj 3233 Matrix Power Series

点击打开poj 3233 思路: 二分求和+矩阵快速幂 分析: 1 题目给定一个n*n的矩阵A,要求(A+A^2+....A^K)%m后的矩阵 2 对于任意的A^x,我们都能够利用矩阵快速幂求出,但是我们现在要求的是和.    仔细观察整个式子,那么我们可以对原式进行变形    如果k为偶数,那么(A+A^2+....A^K) = (A+...+A^K/2)+A^K/2*(A+...+A^K/2)    如果k为奇数,那么(A+A^2+....A^K) = (A+...+A^K/2)+A^K/2

矩阵快速幂专题【完结】

第一题 hdu 1757 A Simple Math Problem 点击打开链接 思路:矩阵快速幂 分析: 1 最简单的矩阵快速幂的题目,直接利用矩阵求解即可 点击打开查看代码 第二题 hdu 1575 Tr A 点击打开hdu 1575 思路: 矩阵快速幂 分析: 1 题目给定一个n*n的矩阵要求矩阵的k次幂之后的矩阵的对角线的和 2 矩阵快速幂的裸题 点击打开查看代码 第三题 hdu 2604 Queuing 点击打开hdu 2604 思路: 递推+矩阵快速幂 分析; 1 根据题目的意思,

UVa 10229 Modular Fibonacci:矩阵快速幂求斐波那契

10229 - Modular Fibonacci Time limit: 3.000 seconds http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=115&page=show_problem&problem=1170 The Fibonacci numbers (0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, ...) are defin

10299 Problem A: Modular Fibonacci(斐波那契的矩阵快速幂)

Problem A: Modular Fibonacci The Fibonacci numbers (0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, ...) are defined by the recurrence: F0 = 0 F1 = 1 Fi = Fi-1 + Fi-2 for i>1 Write a program which calculates Mn = Fn mod 2m for given pair of n and m. 0 n 2147483

HDU 2807 The Shortest Path:最短路+矩阵快速比较

链接: http://acm.hdu.edu.cn/showproblem.php?pid=2807 题目: The Shortest Path Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1421    Accepted Submission(s): 436 Problem Description There are N citi

快速幂

1//整数的快速幂 m^n % k 的快速幂: long long quickpow(long long m , long long n , long long k){ long long ans = 1; while(n){ if(n&1)//如果n是奇数 ans = (ans * m) % k; n = n >> 1;//位运算"右移1类似除2" m = (m * m) % k; } return ans; } 矩阵快速幂 struct Matrix{ int

快速幂取模算法

所谓的快速幂,实际上是快速幂取模的缩写,简单的说,就是快速的求一个幂式的模(余).在程序设计过程中,经常要去求一些大数对于某个数的余数,为了得到更快.计算范围更大的算法,产生了快速幂取模算法.我们先从简单的例子入手:求abmodc 算法1.直接设计这个算法: int ans = 1; for(int i = 1;i<=b;i++) { ans = ans * a; } ans = ans % c; 缺点:这个算法存在着明显的问题,如果a和b过大,很容易就会溢出. 我们先来看看第一个改进方案:在讲

UVa 374 Big Mod:快速幂取模

374 - Big Mod Time limit: 3.000 seconds http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&page=show_problem&problem=310 Calculate for large values of B, P, and M using an efficient algorithm. (That's right, t

c++-UVa1374快速幂运算迭代深搜法 ,C++初学者,求优化方法

问题描述 UVa1374快速幂运算迭代深搜法 ,C++初学者,求优化方法 这是我的代码,优化过几次,但是还是很慢很慢,求大神给优化途经,就是在我的代码的进行优化 #include #include #include #include using namespace std; bool search(int,set&,int dep,int); int MAX=1; int tempMax; int main() { sets;int n; for(n=2;n!=1000;++n) { s.cle