Problem Description
单点时限 | 1.0sec | 内存限制 | 512MB |
---|
小z 学会了斐波那契和
g
c
d
gcd
gcd 后,老师又给他出了个难题,求第N个和第M个斐波那契数的最大公约数,这可难倒了小z ,不过在小z 的再三请求下,老师又告诉他了个条件,
g
c
d
(
N
,
M
)
∈
[
1
,
90
]
gcd(N,M)∈[1,90]
gcd(N,M)∈[1,90]。
可是,笨拙的小z 还是不会,于是请求你帮他解答这个问题。
已知:
F i b o n a c c i [ i ] Fibonacci[i] Fibonacci[i] = { i , i ≤ 1 ; F i b o n a c c i [ i − 1 ] + F i b o n a c c i [ i − 2 ] , i > 1 ; \left\{ \begin{array}{c} i, i\leq1;\\ Fibonacci[i-1]+Fibonacci[i-2],i>1;\end{array}\right. {i,i≤1;Fibonacci[i−1]+Fibonacci[i−2],i>1;
输入格式
输入包括 T 组,
T
∈
[
1
,
10
]
T∈[1,10]
T∈[1,10].
接下来 T 行,每行两个整数 N,M, 表示斐波那契的第 N 项和第 M 项
(
N
,
M
∈
[
1
(N,M∈[1
(N,M∈[1,
1
0
18
10^{18}
1018])
输出格式
输出包含 T 行,每行输出一个整数.
样例
input
3
1 2
2 3
3 4
output
1
1
1
注意:斐波那契数列是从第一项开始的:
F
1
=
1
,
F
2
=
1
,
F
3
=
2........
,
F
0
=
0
F_{1}=1,F_{2}=1,F_{3}=2........,F_{0}=0
F1=1,F2=1,F3=2........,F0=0;
假设
m
≤
m\leq
m≤
n
n
n。
首先显然
g
c
d
(
F
n
,
F
n
−
1
)
=
1
gcd(F_{n},F_{n-1})=1
gcd(Fn,Fn−1)=1。
在模
F
m
F_{m}
Fm 意义下存在:
F
m
+
1
≡
F
m
−
1
,
F
m
+
2
≡
F
m
−
1
,
F
m
+
3
≡
2
F
m
−
1
.
.
.
.
F
n
=
F
n
−
m
F
m
−
1
F_{m+1}\equiv F_{m-1},F_{m+2}\equiv F_{m-1},F_{m+3}\equiv 2F_{m-1}....F_{n}=F_{n-m}F_{m-1}
Fm+1≡Fm−1,Fm+2≡Fm−1,Fm+3≡2Fm−1....Fn=Fn−mFm−1
因此
F
n
F_{n}
Fn%
F
m
=
F
n
−
m
F
m
−
1
F_{m}=F_{n-m}F_{m-1}
Fm=Fn−mFm−1
即
g
c
d
(
F
n
,
F
m
)
=
g
c
d
(
F
m
,
f
n
−
m
F
m
−
1
)
gcd(F_{n},F_{m})=gcd(F_{m},f_{n-m}F_{m-1})
gcd(Fn,Fm)=gcd(Fm,fn−mFm−1)
由
g
c
d
(
F
m
,
F
m
−
1
)
=
1
gcd(F_{m},F_{m-1})=1
gcd(Fm,Fm−1)=1
得到
g
c
d
(
F
n
,
F
m
)
=
g
c
d
(
F
m
,
f
n
−
m
)
gcd(F_{n},F_{m})=gcd(F_{m},f_{n-m})
gcd(Fn,Fm)=gcd(Fm,fn−m)
循环下去得
g
c
d
(
F
n
,
F
m
)
=
g
c
d
(
F
g
c
d
(
n
,
m
)
,
F
0
)
gcd(F_{n},F_{m})=gcd(F_{gcd_{(n,m)},F_{0}})
gcd(Fn,Fm)=gcd(Fgcd(n,m),F0),
所以
g
c
d
(
F
n
,
F
m
)
=
F
g
c
d
(
n
,
m
)
gcd(F_{n},F_{m})=F_{gcd_{(n,m)}}
gcd(Fn,Fm)=Fgcd(n,m);
于是这道题就很简单了给出的最大公约数的范围为1~90;所以对其前90进行打表就
O
K
OK
OK了
接下来上代码:
#include<algorithm>
#include<iostream>
using namespace std;
#define ll long long
ll f[110];
void init()
{
f[0]=0,f[1]=1;
for(int i=2; i<100;i++)
f[i]=f[i-1]+f[i-2];
}
int main()
{
init();
ll n,m,t;
cin>>t;
while(t --)
{
cin>>n>>m;
cout<<f[__gcd(n,m)]<<endl;//__gcd(,)求最大公约数头文件algorithm
}
return 0;
}
实践才是检验真理的唯一标准;