标签:斐波那契数列
题目
题目背景
终于结束的起点
终于写下句点
终于我们告别
终于我们又回到原点
……
一个个 OIer 的竞赛生涯总是从一场 NOIp 开始,大多也在一场 NOIp 中结束,好似一次次轮回在不断上演。
如果这次 NOIp 是你的起点,那么祝你的 OI 生涯如同夏花般绚烂。
如果这次 NOIp 是你的终点,那么祝你的 OI 回忆宛若繁星般璀璨。
也许这是你最后一次在洛谷上打比赛,也许不是。
不过,无论如何,祝你在一周后的比赛里,好运。
当然,这道题也和轮回有关系。
题目描述
广为人知的斐波拉契数列 f i b ( n ) \mathrm{fib}(n) fib(n) 是这么计算的
f i b ( n ) = f i b ( n − 1 ) + f i b ( n − 2 ) ( w h i l e n > 1 ) fib(n)=fib(n-1)+fib(n-2) (while\ n>1) fib(n)=fib(n−1)+fib(n−2)(while n>1)
也就是 0 , 1 , 1 , 2 , 3 , 5 , 8 , 13 ⋯ 0, 1, 1, 2, 3, 5, 8, 13 \cdots 0,1,1,2,3,5,8,13⋯,每一项都是前两项之和。
小 F 发现,如果把斐波拉契数列的每一项对任意大于 1 1 1 的正整数 M M M 取模的时候,数列都会产生循环。
当然,小 F 很快就明白了,因为 ( f i b ( n − 1 )   m o d   M \mathrm{fib}(n - 1) \bmod M fib(n−1)modM) 和 ( f i b ( n − 2 )   m o d   M ) \mathrm{fib}(n - 2) \bmod M) fib(n−2)modM) 最多只有 M 2 M ^ 2 M2 种取值,所以在 M 2 M ^ 2 M2 次计算后一定出现过循环。
甚至更一般地,我们可以证明,无论取什么模数 M M M,最终模 M M M 下的斐波拉契数列都会是 0 , 1 , ⋯   , 0 , 1 , ⋯ 0, 1, \cdots, 0, 1, \cdots 0,1,⋯,0,1,⋯。
现在,给你一个模数 M M M,请你求出最小的 n > 0 n > 0 n>0,使得 f i b ( n )   m o d   M = 0 , f i b ( n + 1 )   m o d   M = 1 \mathrm{fib}(n) \bmod M = 0, \mathrm{fib}(n + 1) \bmod M = 1 fib(n)modM=0,fib(n+1)modM=1。
输入输出格式
输入格式
输入一行一个正整数 M M M。
输出格式
输出一行一个正整数 n n n。
输入输出样例
输入样例#1
2
输出样例#1
3
输入样例#2
6
输出样例#2
24
说明
样例 1 解释
斐波拉契数列为 0 , 1 , 1 , 2 , 3 , 5 , 8 , 13 , 21 , 34 , ⋯ 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, \cdots 0,1,1,2,3,5,8,13,21,34,⋯,在对 2 2 2 取模后结果为 0 , 1 , 1 , 0 , 1 , 1 , 0 , 1 , 1 , 0 , ⋯ 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, \cdots 0,1,1,0,1,1,0,1,1,0,⋯。
我们可以发现,当 n = 3 n = 3 n=3 时, f ( n )   m o d   2 = 0 , f ( n + 1 )   m o d   2 = 1 f(n) \bmod 2= 0, f(n + 1) \bmod 2 = 1 f(n)mod2=0,f(n+1)mod2=1,也就是我们要求的 n n n 的最小值。
数据范围
对于 30 % 30\% 30% 的数据, M ≤ 18 M \leq 18 M≤18;
对于 70 % 70\% 70% 的数据, M ≤ 2018 M \leq 2018 M≤2018;
对于
100
%
100\%
100% 的数据,
2
≤
M
≤
706150
=
2 \leq M \leq 706150=
2≤M≤706150=0xAC666
。
提示
如果你还不知道什么是取模
(
 
m
o
d
 
)
(\bmod)
(mod),那我也很乐意告诉你,模运算是求整数除法得到的余数,也就是竖式除法最终「除不尽」的部分,也即
a
 
m
o
d
 
M
=
k
  
⟺
  
a
=
b
M
+
k
(
M
>
0
,
0
≤
k
<
M
)
a \bmod M =k \iff a = bM + k\ (M > 0, 0 \leq k < M)
amodM=k⟺a=bM+k (M>0,0≤k<M)
其中
a
,
b
,
k
a, b, k
a,b,k 都是非负整数。
如果你使用 C
/ C++
,你可以使用 %
来进行模运算。
如果你使用 Pascal
,你可以使用 mod
来进行模运算。
分析
水题
题目背景好评!!!最喜欢的五月天,最喜欢的自传!
原本还想去推结论和规律
结果发现直接暴力模拟即可,注意爆int
code
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define dep(i,a,b) for(int i=a;i>=b;i--)
#define ll long long
#define mem(x,num) memset(x,num,sizeof x)
#define reg(x) for(int i=last[x];i;i=e[i].next)
using namespace std;
inline ll read(){
ll f=1,x=0;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
//**********head by yjjr**********
ll m,a,b,c,ans;
int main()
{
m=read();
a=0;b=1;c=1;ans=1;
while(1){
ans++;
c=(a+b)%m;a=b;b=c;
if(b%m==0&&a%m==1){cout<<ans<<endl;return 0;}
}
}