欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 建筑 > 【题解】P4994 终于结束的起点

【题解】P4994 终于结束的起点

2024/10/24 7:26:29 来源:https://blog.csdn.net/qianzhima2012/article/details/139783600  浏览:    关键词:【题解】P4994 终于结束的起点

百年更新一次得我

P4994 终于结束的起点题解

文章目录

    • P4994 终于结束的起点题解
      • 题目背景
      • 题目描述
      • 输入格式
      • 输出格式
      • 样例 #1
        • 样例输入 #1
        • 样例输出 #1
      • 样例 #2
      • 样例输入 #2
      • 样例输出 #2
    • 提示
        • 样例 1 解释
        • 数据范围
        • 提示
    • 题目大意
    • 思路
    • 代码

原题:

题目背景

终于结束的起点
终于写下句点
终于我们告别
终于我们又回到原点
……

一个个 OIer 的竞赛生涯总是从一场 NOIp 开始,大多也在一场 NOIp 中结束,好似一次次轮回在不断上演。
如果这次 NOIp 是你的起点,那么祝你的 OI 生涯如同夏花般绚烂。
如果这次 NOIp 是你的终点,那么祝你的 OI 回忆宛若繁星般璀璨。
也许这是你最后一次在洛谷上打比赛,也许不是。
不过,无论如何,祝你在一周后的比赛里,好运。

当然,这道题也和轮回有关系。

题目描述

广为人知的斐波拉契数列 f i b ( n ) \mathrm{fib}(n) fib(n) 是这么计算的

f i b ( n ) = { 0 , n = 0 1 , n = 1 f i b ( n − 1 ) + f i b ( n − 2 ) , n > 1 \mathrm{fib}(n)=\begin{cases} 0,& n=0 \\ 1,& n=1 \\ \mathrm{fib}(n-1) + \mathrm{fib}(n-2),& n>1 \end{cases} fib(n)= 0,1,fib(n1)+fib(n2),n=0n=1n>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(n1)modM) 和 ( f i b ( n − 2 ) m o d M ) \mathrm{fib}(n - 2) \bmod M) fib(n2)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

样例输入 #1
2
样例输出 #1
3

样例 #2

样例输入 #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 M18

对于 70 % 70\% 70% 的数据, M ≤ 2018 M \leq 2018 M2018

对于 100 % 100\% 100% 的数据, 2 ≤ M ≤ 706150 = 0xAC666 2 \leq M \leq 706150=\verb!0xAC666! 2M706150=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=ka=bM+k (M>0,0k<M)
其中 a , b , k a, b, k a,b,k 都是非负整数。

如果你使用 C / C++,你可以使用 % 来进行模运算。

如果你使用 Pascal,你可以使用 mod 来进行模运算。

题目大意

现在,给你一个模数 M M M,请你求出最小的 n > 0 n > 0 n>0,使得
fib( n n n) m o d mod mod M M M = = = 0 0 0, fib( n + 1 n+1 n+1) m o d mod mod M M M = = = 1 1 1

思路

一开始想找数学方法过
但是后来有一位大佬的分享
就让我想起了滚存

思路是用 f [ 0 ] , f [ 1 ] , f [ 2 ] f[0],f[1],f[2] f[0],f[1],f[2]只要给变量就可以进行滚动存储

f [ 2 ] f[2] f[2]是一个用来辅助用的数组(有点像我交换时常用的tmp)

f [ 0 ] f[0] f[0]是上一个数

f [ 1 ] f[1] f[1]是当前数

后来呐?
没后来辣,上代码

代码

int a[N];
int m;
void solve() {int m; cin >> m;a[0] = 0;a[1] = 1;a[2] = 1;for(int i = 1; ; i++){a[2] = a[0];a[0] = a[1];a[1] = (a[2] + a[1]) % m;if (a[0] % m == 0 && a[1] % m == 1){cout << i << endl;return;}}
}

拜拜┏(^0^)┛

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com