HDU 4549 M斐波那契數列(矩陣快速冪+費馬小定理)
M斐波那契數列
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 3476 Accepted Submission(s): 1080
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]的值嗎?
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 )
每組資料佔一行,包含3個整數a, b, n( 0 <= a, b, n <= 10^9 )
Output
對每組測試資料請輸出一個整數F[n],由於F[n]可能很大,你只需輸出F[n]對1000000007取模後的值即可,每組資料輸出一行。
Sample Input
0 1 0
6 10 2
Sample Output
0
60
Source
中文題意。
POINT://其實還沒學過矩陣到底怎麼算,只知道2乘2的。
學習矩陣快速冪,可以用來求斐波那契數列。畢竟n非常大,遞迴肯定超時。
自己理解了一下,寫了一個很醜的矩陣快速冪,只能求斐波那契數列。
費馬小定理2:
我們可以利用費馬小定理來簡化冪模運算:由於a^(p-1)≡a^0≡1(mod p),所以a^x(mod p)有迴圈節,長度為p-1,所以a^x≡a^(x%(p-1))(mod p)
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <stack>
#include <algorithm>
#include <math.h>
using namespace std;
#define ll long long
const ll p =1e9+7;
const ll m=p-1;
ll a,b,n;
struct node
{
ll x11,x12,x21,x22;
};
node chen(node a,node b)
{
node ans;
(ans.x11=a.x11*b.x11+a.x12*b.x21)%=m;
(ans.x12=a.x11*b.x12+a.x12*b.x22)%=m;
(ans.x21=a.x21*b.x11+a.x22*b.x21)%=m;
(ans.x22=a.x21*b.x12+a.x22*b.x22)%=m;
return ans;
}
node jqkm(node now,ll mi)
{
if(mi<=0) return now;
node ans;
ans.x11=1,ans.x12=0,ans.x21=0,ans.x22=1;
while(mi)
{
if(mi&1)
{
ans=chen(ans,now);
}
mi=mi>>1;
now=chen(now,now);
}
return ans;
}
ll qkm(ll now, ll mi)
{
ll ans=1;
while(mi)
{
if(mi&1)
(ans*=now)%=p;
mi=mi>>1;
(now=now*now)%=p;
}
return ans;
}
ll baoli(ll x)
{
if(x==0) return a;
if(x==1) return b;
return baoli(x-1)*baoli(x-2)%p;
}
int main()
{
while(~scanf("%lld %lld %lld",&a,&b,&n))
{
ll f1=1,f2=2;
ll na,nb;
if(n<4)
{
printf("%lld\n",baoli(n));
}
else
{
node ans;
node now;
now.x11=1,now.x12=1,now.x21=1,now.x22=0;
ans=jqkm(now,n-3);
nb=ans.x11*f2+ans.x12*f1;
na=ans.x21*f2+ans.x22*f1;
printf("%lld\n",qkm(a,na)*qkm(b,nb)%p);
}
}
}
相關文章
- 從斐波那契到矩陣快速冪矩陣
- 斐波那契數列Ⅳ【矩陣乘法】矩陣
- 費馬小定理 + 費馬大定理 + 勾股數的求解 + 快速冪 + 矩陣快速冪 【模板】矩陣
- 斐波那契數列數與等冪和
- 斐波那契數列
- 斐波那契數列(Java)Java
- 第六章 數學問題 -------- 6.14 【快速冪】斐波那契數列
- 斐波那契數列詳解
- 著名的斐波那契數列
- 斐波那契數列 (C#)C#
- PHP 與斐波那契數列PHP
- 斐波那契數
- [C103] 斐波那契數列
- 力扣之斐波那契數列力扣
- 斐波那契數列js 實現JS
- 劍指offer——斐波那契數列
- js實現斐波那契數列JS
- 斐波那契數列演算法演算法
- 第十題:斐波那契數列
- No.8 遞迴快速輸出斐波那契數列遞迴
- 使用Python實現斐波那契數列Python
- 演算法(1)斐波那契數列演算法
- 斐波那契數列的來源——數兔子
- LeetCode 509[斐波那契數]LeetCode
- Leedcode-斐波那契數
- 509. 斐波那契數
- 一千位斐波那契數
- JavaScript 實現:輸出斐波那契數列JavaScript
- js迭代器實現斐波那契數列JS
- offer通過--9斐波那契數列-2
- 演算法一:斐波那契阿數列演算法
- 大數斐波那契數列的演算法演算法
- HDU 1005 Number Sequence(矩陣快速冪)矩陣
- 斐波那契數列:7數5層魔法塔(3)
- 斐波那契數列:7數5層魔法塔(2)
- 斐波那契數列:7數5層魔法塔(5)
- 斐波那契數列:7數5層魔法塔(8)
- 斐波那契數列:7數5層魔法塔(13)