矩阵快速幂---BestCoder Round#8 1002

当要求递推数列的第n项且n很大时,怎么快速求得第n项呢?
可以用矩阵快速幂来加速计算。
我们可以用矩阵来表示数列递推公式
比如fibonacci数列 可以表示为 [f(n)   f(n-1)] = [f(n-1)    f(n-2)] [ 1 1 ]

                              [ 1 0 ] 
设A = [ 1 1 ]

    [ 1 0 ]

[f(n)   f(n-1)] = [f(n-2)   f(n-3)]*A*A
[f(n)   f(n-1)] = [f(2)   f(1)]*A^(n-2)
矩阵满足结合律,所以先计算A^(n-2),这个可以用一般快速二分幂的思想来计算。

BestCoder Round#8 1002
当n为奇数时,f(n) = 2 * f(n-1) + 1
当n为偶数时,f(n) = 2 * f(n-1)
将偶数项独立出来形成单独的一个数列 b(2*n) = 2 * b(2*n-1) + 1 = 4 * (2*n-2) + 2
即b(n) = 4 * b(n-1) + 2
当n为偶数时,计算b(n/2)即可
当n为奇数时,计算b(n/2) * 2 + 1即可
因为n很大,可以用矩阵快速幂来加速
递推矩阵为 [b(n)   2] = [b(n-1]   2] * [ 4 0 ]
                     [ 1 1 ]

 1 #include <stdio.h>
 2 #include <string.h>
 3 typedef long long LL;
 4 struct Matrix
 5 {
 6     LL matrix[2][2];
 7 };
 8 int n,m;
 9 Matrix operator *(const Matrix &lhs, const Matrix &rhs)
10 {
11     Matrix res;
12     memset(res.matrix, 0 ,sizeof(res.matrix));
13     int i,j,k;
14     for(k=0; k<2; ++k)
15         for(i=0; i<2; ++i)
16         {
17             if(lhs.matrix[i][k] == 0) continue;
18             for(j=0; j<2; ++j)
19             {
20                 if(rhs.matrix[k][j] == 0) continue;
21                 res.matrix[i][j] = (res.matrix[i][j] + lhs.matrix[i][k] * rhs.matrix[k][j]) % m;
22             }
23         }
24     return res;
25 }
26 Matrix operator ^(Matrix a, int k)
27 {
28     Matrix res;
29     int i,j;
30     for(i=0; i<2; ++i)
31         for(j=0; j<2; ++j)
32             res.matrix[i][j] = (i == j);
33     while(k)
34     {
35         if(k & 1)
36             res = res * a;
37         a = a * a;
38         k>>=1;
39     }
40     return res;
41 }
42
43 int main()
44 {
45     while(scanf("%d%d",&n,&m)!=EOF)
46     {
47         Matrix a;
48         a.matrix[0][0] = 4;
49         a.matrix[0][1] = 0;
50         a.matrix[1][0] = a.matrix[1][1] = 1;
51         int k = n / 2;
52         a = a ^ k;
53         LL ans =(2 * a.matrix[1][0]) % m;
54         if(n & 1 == 1)
55             ans = (ans * 2 + 1) % m;
56         printf("%lld\n",ans);
57
58
59     }
60     return 0;
61 }

时间: 2024-10-12 04:35:14

矩阵快速幂---BestCoder Round#8 1002的相关文章

BestCoder Round #29——A--GTY&#39;s math problem(快速幂(对数法))、B--GTY&#39;s birthday gift(矩阵快速幂)

GTY's math problem Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 0    Accepted Submission(s): 0 Problem Description GTY is a GodBull who will get an Au in NOI . To have more time to learn alg

Codeforces Round #291 (Div. 2) E - Darth Vader and Tree (DP+矩阵快速幂)

这题想了好长时间,果断没思路..于是搜了一下题解.一看题解上的"快速幂"这俩字,不对..这仨字..犹如醍醐灌顶啊...因为x的范围是10^9,所以当时想的时候果断把dp递推这一方法抛弃了.我怎么就没想到矩阵快速幂呢.......还是太弱了..sad..100*100*100*log(10^9)的复杂度刚刚好. 于是,想到了矩阵快速幂后,一切就变得简单了.就可以把距离<=x的所有距离的点数都通过DP推出来,然后一个快速幂就解决了. 首先DP递推式很容易想到.递推代码如下: for(

Codeforces Round #257 (Div. 2) B. Jzzhu and Sequences (矩阵快速幂)

题目链接:http://codeforces.com/problemset/problem/450/B 题意很好懂,矩阵快速幂模版题. 1 /* 2 | 1, -1 | | fn | 3 | 1, 0 | | fn-1 | 4 */ 5 #include <iostream> 6 #include <cstdio> 7 #include <cstring> 8 using namespace std; 9 typedef __int64 LL; 10 LL mod =

Codeforces Round #257 (Div. 2)B 矩阵快速幂

B. Jzzhu and Sequences time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Jzzhu has invented a kind of sequences, they meet the following property: You are given x and y, please calculate fn m

Educational Codeforces Round 60 (Rated for Div. 2) D. Magic Gems(矩阵快速幂)

题目传送门 题意: 一个魔法水晶可以分裂成m个水晶,求放满n个水晶的方案数(mol1e9+7) 思路: 线性dp,dp[i]=dp[i]+dp[i-m]; 由于n到1e18,所以要用到矩阵快速幂优化 注意初始化 代码: #include<bits/stdc++.h> using namespace std; #define mod 1000000007 typedef long long ll; #define MAX 105 const int N=105;//矩阵的大小 int T; ll

Product Oriented Recurrence(Codeforces Round #566 (Div. 2)E+矩阵快速幂+欧拉降幂)

传送门 题目 \[ \begin{aligned} &f_n=c^{2*n-6}f_{n-1}f_{n-2}f_{n-3}&\\end{aligned} \] 思路 我们通过迭代发现\(f_n\)其实就是由\(c^{x_1},f_1^{x_2},f_2^{x_3},f_3^{x_4}\)相乘得到,因此我们可以分别用矩阵快速幂求出\(x_1,x_2,x_3,x_4\),最后用快速幂求得答案. 对\(f_1,f_2,f_3\): \[ \begin{aligned} (x_n&&

Codeforces Round #518 (Div. 1) Computer Game 倍增+矩阵快速幂

接近于死亡的选手没有水平更博客,所以现在每五个月更一篇. 这道题呢,首先如果已经有权限升级了,那么后面肯定全部选的是 \(p_ib_i\) 最高的. 设这个值为 \(M=\max \limits_i p_ib_i\). 主要的问题在于前面怎么选. 假设剩下的时间还有 \(t\) 秒.那么我们很容易得到一个这样的式子. \[ dp[t+1] = \max_i \{p_i \cdot (a_i+tM) + (1-p_i) \cdot dp[t]\} \] 把 \(\max\)里面的内容整理一下. \

HDU 4990 Reading comprehension(找规律+矩阵快速幂)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4990 Problem Description Read the program below carefully then answer the question. #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include<iostream> #include

HDU5171 GTY&#39;s birthday gift(矩阵快速幂)

Problem Description FFZ's birthday is coming. GTY wants to give a gift to ZZF. He asked his gay friends what he should give to ZZF. One of them said, 'Nothing is more interesting than a number multiset.' So GTY decided to make a multiset for ZZF. Mul