洛谷1349 广义斐波那契数列 【矩阵乘法】

洛谷1349 广义斐波那契数列

题目描述

广义的斐波那契数列是指形如an=p*an-1+q*an-2的数列。今给定数列的两系数p和q,以及数列的最前两项a1和a2,另给出两个整数n和m,试求数列的第n项an除以m的余数。

输入输出格式

输入格式:

输入包含一行6个整数。依次是p,q,a1,a2,n,m,其中在p,q,a1,a2整数范围内,n和m在长整数范围内。

输出格式:

输出包含一行一个整数,即an除以m的余数。

输入输出样例

输入样例#1:

1 1 1 1 10 7

输出样例#1:

6

说明

数列第10项是55,除以7的余数为6。

【思路】

矩阵乘法。

n最大为maxlongint所以枚举肯定会有TLE。

这里用到了矩阵乘法。大体思想:因为每次的求解规则相同,所以可以构造一个转移矩阵,使得每个点与该矩阵相乘即可直接得出最终该点的位置。

开始矩阵B:

a2 a1

构造矩阵如下:

P 1

Q 0

(一次转换后为
p*a2+q*a1,a2 )

因为要进行n-2次相同的转换所以用快速幂求解转换n-2次后的A’ 。

ans=B*A‘

注意: 矩阵乘法的顺序不能更改,否则可能不满足乘法要求。

LL 与 LL的乘法可能会爆精度,可以转化为小数相加的形式。

代码思想源于洛谷题解。

【代码】

 1 #include<iostream>
 2 #include<cstring>
 3 using namespace std;
 4
 5 typedef long long LL;
 6 const int delen=23,delta=1<<23,deltb=delta-1;
 7 LL n,m,p,q,a1,a2;
 8
 9 LL Add(LL x,LL y) {
10     x+=y;
11     if(x>=m) x-=m;
12     return x;
13 }
14
15 LL multi(LL x,LL y) {  //对于long long型的 乘法+模 防止越界
16     LL ans=0;
17     while(y) {
18         if(y&deltb) ans=Add(ans,x*(y&deltb)%m);
19         x=x*delta%m;
20         y>>=delen;
21     }
22     return ans;
23 }
24
25 struct Matrix{
26     int r,c;
27     LL N[5][5];
28     Matrix operator *(const Matrix& rhs) const{
29         Matrix tmp={};
30         tmp.r=r, tmp.c=rhs.c;
31         for(int i=0;i<tmp.r;i++)
32           for(int j=0;j<tmp.c;j++) {
33                 for(int k=0;k<c;k++)  tmp.N[i][j] += multi(N[i][k],rhs.N[k][j]);
34                 tmp.N[i][j] %= m;
35           }
36         return tmp;
37     }
38
39     Matrix pow(LL p) const{
40         Matrix ans={} , tmp=*this;
41         ans.r=ans.c=r;
42         for(int i=0;i<r;i++) ans.N[i][i]=1;
43         while(p) {
44             if(p&1) ans=ans*tmp;
45             tmp=tmp*tmp;
46             p>>=1;
47         }
48         return ans;
49     }
50 };
51
52 int main() {
53     cin>>p>>q>>a1>>a2>>n>>m;
54     Matrix A,B;
55     A.r=A.c=2;
56     A.N[0][0]=p , A.N[1][0]=q , A.N[0][1]=1 , A.N[1][1]=0; //0
57     A=A.pow(n-2);
58
59     B.r=1 , B.c=2;
60     B.N[0][0]=a2,B.N[0][1]=a1;
61
62     B=B*A;    //B*A
63
64     cout<<B.N[0][0]%m;
65     return 0;
66 }
时间: 2024-10-13 00:43:02

洛谷1349 广义斐波那契数列 【矩阵乘法】的相关文章

洛谷P1962 斐波那契数列 || P1349 广义斐波那契数列[矩阵乘法]

P1962 斐波那契数列 大家都知道,斐波那契数列是满足如下性质的一个数列: • f(1) = 1 • f(2) = 1 • f(n) = f(n-1) + f(n-2) (n ≥ 2 且 n 为整数) 题目描述 请你求出 f(n) mod 1000000007 的值. 输入输出格式 输入格式: ·第 1 行:一个整数 n 输出格式: 第 1 行: f(n) mod 1000000007 的值 输入输出样例 输入样例#1: 5 输出样例#1: 5 输入样例#2: 10 输出样例#2: 55 说明

P1349 广义斐波那契数列(矩阵乘法)

题目 P1349 广义斐波那契数列 解析 把普通的矩阵乘法求斐波那契数列改一改,随便一推就出来了 \[\begin{bmatrix}f_2\\f_1 \end{bmatrix}\begin{bmatrix} p&q\1&0\\end{bmatrix}^{n-2}=\begin{bmatrix}f_n\\f_{n-1} \end{bmatrix}\] 水题 代码 #include <bits/stdc++.h> #define int long long using namesp

HDU 5451 广义斐波那契数列

这道题目可以先转化: 令f(1) = 5+2√6 f(2) = f(1)*(5+2√6) ... f(n) = f(n-1)*(5+2√6) f(n) = f(n-1)*(10-(5-2√6)) = 10*f(n-1)-(5-2√6)f(n-1) = 10*f(n-1) - 10/(5+2√6) f(n-1) = 10*f(n-1) - 10/(5+2√6) * (5+2√6)f(n-2) = 10*f(n-1) - f(n-2) 那么就可以写成矩阵相乘的形式了 (f(n) , f(n-1))

矩阵乘法快速幂 codevs 1574 广义斐波那契数列

codevs 1574 广义斐波那契数列 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题目描述 Description 广义的斐波那契数列是指形如an=p*an-1+q*an-2的数列.今给定数列的两系数p和q,以及数列的最前两项a1和a2,另给出两个整数n和m,试求数列的第n项an除以m的余数. 输入描述 Input Description 输入包含一行6个整数.依次是p,q,a1,a2,n,m,其中在p,q,a1,a2整数范围内,n和m在长整数范围

HDU 4549 M斐波那契数列 ( 矩阵快速幂 + 费马小定理 )

HDU 4549 M斐波那契数列 (  矩阵快速幂 + 费马小定理  ) 题意:中文题,不解释 分析:最好的分析就是先推一推前几项,看看有什么规律 #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef __int64 LL; #define CLR( a, b ) memset( a, b, sizeof(a) ) #define MOD 100000

P1349 广义斐波那契数列

题目描述 广义的斐波那契数列是指形如an=p×an−1+q×an−2an=p\times a_{n-1}+q\times a_{n-2}an=p×an−1?+q×an−2?的数列.今给定数列的两系数ppp和qqq,以及数列的最前两项a1a_1a1?和a2a_2a2?,另给出两个整数nnn和mmm,试求数列的第nnn项ana_nan?除以mmm的余数. 输入格式 输入包含一行6个整数.依次是p,q,a1?,a2?,n,m,其中在p,q,a1?,a2?整数范围内,n和m在长整数范围内. 输出格式 输

HDU 4549 M斐波那契数列(矩阵快速幂&amp;费马小定理)

ps:今天和战友聊到矩阵快速幂,想到前几天学长推荐去刷矩阵专题,挑了其中唯一一道中文题,没想到越过山却被河挡住去路... 题目链接:[kuangbin带你飞]专题十九 矩阵 R - M斐波那契数列 Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u 题意 Description M斐波那契数列F[n]是一种整数数列,它的定义如下: F[0] = a F[1] = b F[n] = F[n-1] * F[n-2]

hdu4549---M斐波那契数列(矩阵+欧拉定理)

Problem Description M斐波那契数列F[n]是一种整数数列,它的定义如下: F[0] = a F[1] = b F[n] = F[n-1] * F[n-2] ( n > 1 ) 现在给出a, b, n,你能求出F[n]的值吗? Input 输入包含多组测试数据: 每组数据占一行,包含3个整数a, b, n( 0 <= a, b, n <= 10^9 ) Output 对每组测试数据请输出一个整数F[n],由于F[n]可能很大,你只需输出F[n]对1000000007取模

hdu 4549 M斐波那契数列 矩阵快速幂+欧拉定理

M斐波那契数列 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Problem Description M斐波那契数列F[n]是一种整数数列,它的定义如下: F[0] = aF[1] = bF[n] = F[n-1] * F[n-2] ( n > 1 ) 现在给出a, b, n,你能求出F[n]的值吗? Input 输入包含多组测试数据:每组数据占一行,包含3个整数a, b,