题目描述
月月要参加学校的信息学集训,晚上不能陪华华聊天了。不过为了防止华华去和别的小姐姐聊天,浪费时间影响学习,所以月月给华华布置了一项任务。月月给了华华一个类似斐波那契数列的东西,这个数列满足:
F
1
=
A
,
F
2
=
B
,
F
i
=
F
i
−
1
+
F
i
−
2
(
i
>
2
)
F_1=A,F_2=B,F_i=F_{i-1}+F_{i-2}(i>2)
F1=A,F2=B,Fi=Fi−1+Fi−2(i>2)
月月希望华华求出
g
c
d
(
F
N
,
F
N
+
1
)
gcd(F_N,F_{N+1})
gcd(FN,FN+1)。月月认为,求这个东西需要很长的时间,所以华华就没有机会去和其他小姐姐聊天了。华华自然对月月十分忠诚,选择求出F的每一位后计算答案。但是比赛中的你看到这一题,就没必要那么老实了。现在给定A、B、N,请你求出月月要求的那个数字。答案可能很大,但是不取模。
输入描述
输入一行三个正整数A,B,N。
输出描述
输出一行一个正整数表示答案。
示例1
输入 |
---|
2 4 5 |
输出 |
2 |
说明 |
F序列如下:2,4,6,10,16,26,…… |
第N项16和第N+1项26的最大公约数为2,故答案输出2。 |
备注: |
---|
1 ≤ A ≤ B ≤ 1 0 1 7 , 1 ≤ N ≤ 1 0 1 0 5 1 \leq A \leq B \leq 10^17,1 \leq N \leq 10^{10^5} 1≤A≤B≤1017,1≤N≤10105,也就是说N的长度不超过 1 0 5 10^5 105 |
题目大意
给你一个类似于斐波那契数的递推公式 F 1 = A , F 2 = B , F i = F i − 1 + F i − 2 ( i > 2 ) F_1=A,F_2=B,F_i=F_{i-1}+F_{i-2}(i>2) F1=A,F2=B,Fi=Fi−1+Fi−2(i>2),求出 g c d ( F N , F N + 1 ) gcd(F_N,F_{N+1}) gcd(FN,FN+1)。
解题思路
看到题目中N的数据范围就能猜到这道题应该是与N无关的,明显就是一道规律题。当时猜测 g c d ( F N , F N + 1 ) = g c d ( A , B ) gcd(F_N,F_{N+1})=gcd(A,B) gcd(FN,FN+1)=gcd(A,B)。没想到是对的,但具体证明在看到题解才明白。
证明如下:
F
i
=
F
i
−
1
+
F
i
−
2
F_i=F_{i-1}+F_{i-2}
Fi=Fi−1+Fi−2,则
g
c
d
(
F
N
,
F
N
+
1
)
gcd(F_N,F_{N+1})
gcd(FN,FN+1)=
g
c
d
(
F
N
,
F
N
−
1
+
F
N
)
gcd(F_N,F_{N-1}+F_N)
gcd(FN,FN−1+FN)=
g
c
d
(
F
N
,
F
N
−
1
)
gcd(F_N,F_{N-1})
gcd(FN,FN−1)
这样递归下去的话,最终可以得到 g c d ( F N , F N + 1 ) gcd(F_N,F_{N+1}) gcd(FN,FN+1)= g c d ( F 1 , F 2 ) gcd(F_1,F_2) gcd(F1,F2)。
所以这道题最后就是求 g c d ( A , B ) gcd(A,B) gcd(A,B)
AC代码
#include<bits/stdc++.h>
using namespace std;
const int Max_N=1e3+6;
typedef unsigned long long ull;
typedef long long ll;
ull gcd(ull a,ull b)
{
if(b==0)
return a;
return gcd(b,a%b);
}
int main()
{
ull a,b;
cin>>a>>b;
string n;
cin>>n;
ull res=gcd(a,b);
cout<<res<<endl;
}
总结
像这样的题目,就可以大胆假设,先提交一次。若错了,那么才小心验证,从数学的角度来思考。