如题,毕克老师给我们出的noip(NOIplus)模拟赛的\(Day1T1\)

首先我们知道斐波那契数列的特征根
\[\phi_1=\frac{1+\sqrt{5}}{2}\]
\[\phi_2=\frac{1-\sqrt{5}}{2}\]
于是
\[F_n=\frac{\phi_1^n-\phi_2^n}{\sqrt{5}}\]

对于不为\(5\)的质数\(p\)

若\(5\)是模\(p\)意义下的二次剩余

设最小循环节长度为\(m\)
那么\(\phi_1,\phi_2\)是模\(p\)的完全剩余系中的元素
根据费马小定理
\[\phi_1^{p-1} \equiv 1 \mod p​\]
\[\phi_2^{p-1} \equiv 1 \mod p​\]
\[F_{p-1} \equiv \frac{\phi_1^{p-1}-\phi_2^{p-1}}{\sqrt{5}} \equiv 0 \mod p\]
\[F_{p} \equiv \frac{\phi_1^{p}-\phi_2^{p}}{\sqrt{5}} \equiv \frac{\phi_1-\phi_2}{\sqrt{5}} \equiv 1 \mod p\]
\[m | p-1\]

若\(5\)是模\(p\)意义下的二次非剩余

设最小循环节长度为\(m\)
根据欧拉判别准则
\[ 5^{\frac{p-1}{2}} \equiv -1 \mod p\]
\[ \phi_1^p \equiv (\frac{1+\sqrt{5}}{2})^p \equiv (\frac{1}{2})^p (1+\sqrt{5})^p \equiv (\frac{1}{2})^p (1+\sqrt{5}^p) \equiv \frac{1}{2} (1+5^{\frac{p-1}{2}} \sqrt{5}) \equiv \phi_2 \mod p\]
同理可得
\[ \phi_2^p \equiv \phi_1 \mod p\]
\[ F_{2p+1} \equiv \frac{\phi_1^{2p+1}-\phi_2^{2p+1}}{\sqrt{5}} \equiv \frac{\phi_1^{2p}\phi_1-\phi_2^{2p}\phi_2}{\sqrt{5}} \equiv \frac{\phi_2^{2}\phi_1-\phi_1^{2}\phi_2}{\sqrt{5}} \equiv \phi_1\phi_2\frac{\phi_2-\phi_1}{\sqrt{5}} \equiv 1 \mod p\]
\[ F_{2p+2} \equiv \frac{\phi_1^2\phi_2^2-\phi_2^2\phi_1^2}{\sqrt{5}} \equiv 0 \mod p\]
\[ F_{2p+3} \equiv F_{2p+1}+ F_{2p+2}\equiv 1 \mod p \]
\[m|2p+2\]

对于质数的幂\(p^k\)

设模\(p\)意义下的最小循环节长度为\(m\),模\(p^k\)意义下的最小循环节长度为\(m'\)
\[ F_m \equiv \frac{\phi_1^m-\phi_2^m}{\sqrt{5}} \equiv 0 \mod p\]
\[ \phi_1^m \equiv \phi_2^m \mod p \]
\[ F_{m+1} \equiv F_1 \mod p\]
\[ \phi_1^{m+1}-\phi_2^{m+1}-\phi_1+\phi_2\equiv \phi_1(\phi_1^m-1)-\phi_2(\phi_2^m - 1) \equiv ( \phi_1-\phi_2)(\phi_1^m-1) \equiv 0 \mod p\]
\[ \phi_1^m \equiv \phi_2^m \equiv 1 \mod p\]
\[ {(\phi_1^m)}^{p^{k-1}} \equiv {(\phi_2^m)}^{p^{k-1}} \equiv 1 \mod p^k\]
注:这里引用了一个定理

若\(a \equiv 1 \mod p\),则\(a^{p^k} \equiv 1 \mod p^{k+1}\)

可以用数学归纳法证明
\(k=1\)时,令\(a=np+1\)有
\[ a^p \equiv (np+1)^p \equiv \sum_{i=0}^{p}{C_p^i* (np)^p} \equiv 1+p*(np)+\sum_{i=2}^{p}{C_p^i* (np)^p} \equiv 1 \mod p^2\]
若当\(k=m\)时成立,令\(a^{p^m}=np^{m+1}+1\)有
\[ a^{p^{m+1}} \equiv (a^{p^m})^p \equiv (np^{m+1}+1)^p \equiv 1+p*np^{m+1}+\sum_{i=2}^{p}{C_p^i *(np^{m+1})^p} \equiv 1 \mod p^{m+2} \]
得证

所以
\[ F_{mp^{k-1}} \equiv 0 \mod p^k\]
\[ F_{mp^{k-1}+1} \equiv 1 \mod p^k\]
\[ m'|mp^{k-1}\]

注:
就我所知对于目前已知的所有情况,都有$ m'=mp^{k-1} $
然而我所能查到的论文都说数学上还没有证明
如果哪位大佬知道请赐教……

对于合数\(p_1^{k_1}*p_2^{k_2}*...*p_c^{k_c}\)

设模\(p_1^{k_1}*p_2^{k_2}*...*p_c^{k_c}\)意义下的最小循环节长度为\(m\)
\[ F_m \equiv 0 \mod p_1^{k_1}*p_2^{k_2}*...*p_c^{k_c} \]
\[ F_{m+1} \equiv 1 \mod p_1^{k_1}*p_2^{k_2}*...*p_c^{k_c} \]
中国剩余定理
\[ F_m \equiv 0 \mod p_1^{k_1}\]
\[ F_{m+1} \equiv 1 \mod p_1^{k_1}\]
\[ F_m \equiv 0 \mod p_2^{k_1}\]
\[ F_{m+1} \equiv 1 \mod p_2^{k_1}\]
\[ ... \]
\[ F_m \equiv 0 \mod p_c^{k_c}\]
\[ F_{m+1} \equiv 1 \mod p_c^{k_c}\]
所以在模\(p_i^{k_i}\)意义下分别求解
答案取\(lcm\)即可

优化&总结&代码

关于判断\(5\)是否是模\(p\)(\(p\)为奇素数且\(p \neq 5\))意义下的二次剩余
可以直接用欧拉判别准则
但是需要快速幂,带一个\(log\)
我们还可以考虑优化这个算法
二次互反律
可以得到
\[(\frac{5}{p})=(\frac{p}{5})(-1)^{\frac{(5-1)(p-1)}{4}}=(\frac{p}{5})\]
因为
\[ (\frac{1}{5}) = (\frac{4}{5}) =1 \]
\[ (\frac{2}{5}) = (\frac{3}{5}) =-1 \]
所以
当且仅当\(p \equiv 1 \mod 5\)或\(p \equiv 4 \mod 5\)时\(5\)是模\(p\)意义下的二次剩余
当且仅当\(p \equiv 2 \mod 5\)或\(p \equiv 3 \mod 5\)时\(5\)是模\(p\)意义下的二次非剩余

\(2\)和\(5\)比较特殊
同样由二次互反律可以注意到\(2\)的条件是相反的
而\(5\)则不在以上所有讨论范围内,没有理论上的证明
然而不是有样例吗……
所以小于等于\(5\)的我都直接返回答案了(实际上\(1e6\)内都可以暴力跑出来)
对于其它质数求解时直接枚举\(p-1\)或\(2p+2\)的约数判断即可

然后这道题就完美地做完了

#include<bits/stdc++.h>using namespace std;#define gc c=getchar()
#define r(x) read(x)
#define ll long longtemplate<typename T>
inline void read(T&x){x=0;T k=1;char gc;while(!isdigit(c)){if(c=='-')k=-1;gc;}while(isdigit(c)){x=x*10+c-'0';gc;}x*=k;
}const int N=5e4+7;int tot;
int pri[N];
bool mark[N];inline void init(){for(int i=2;i<N;++i){if(!mark[i])pri[++tot]=i;for(int j=1,tmp;j<=tot&&(tmp=i*pri[j])<N;++j){mark[tmp]=1;if(i%pri[j]==0)break;}}
}int p;inline int add(int a,int b){a+=b;if(a>=p)a-=p;return a;
}inline int mul(int a,int b){return (ll)a*b%p;
}inline int spr(int a){return mul(a,a);
}ll gcd(ll a,ll b){return b?gcd(b,a%b):a;
}ll lcm(ll a,ll b){return a/gcd(a,b)*b;
}map<int,int>F;int fib(int n){if(n<=1)return n;int &ans=F[n];if(ans)return ans;if(n&1)return ans=add(spr(fib((n+1)>>1)),spr(fib((n-1)>>1)));int tmp=fib(n>>1);return ans=mul(tmp,add(mul(2,fib((n>>1)-1)),tmp));
}vector<int> d;inline void div(int x){int t=sqrt(x);d.clear();for(int i=2;i<t;++i){if(x%i==0){d.push_back(i);d.push_back(x/i);}}if(t*t==x)d.push_back(t);sort(d.begin(), d.end());
}inline int check(int x){div(x);F.clear();for(int i=0;i<d.size();++i){if(fib(d[i])==0&&fib(d[i]+1)==1)return d[i];}
//  assert(fib(x)==0&&fib(x+1)==1);return x;}inline int query(int x){if(x==2)return 3;if(x==3)return 8;if(x==5)return 20;p=x;if(x%5==1||x%5==4)return check(x-1);if(x%5==2||x%5==3)return check(2*x+2);
//  assert(0);
}inline ll solve(int n){ll ans=1;for(int i=1;i<=tot;++i){if(pri[i]>n)break;if(n%pri[i]==0){n/=pri[i];ll t=1;while(n%pri[i]==0){n/=pri[i];t*=pri[i];}ans=lcm(ans,t*query(pri[i]));}}if(n>1){ans=lcm(ans,query(n));}return ans;
}int main(){init();int T;for(r(T);T;--T){int n;r(n);printf("%lld\n",solve(n));}
}

后记&其它做法

毕老师:“其实我只是想考察大家的找规律技巧,noip不会考证明的”
我:“其实我也只是自己感兴趣而已”

如果感兴趣可以看看这个网站以及它推荐的其它网站
OEIS也还行
我觉得在网上花些时间认真看论文还是有收获的,遗憾的是几乎没有中文资料,所以自己来写一写
学信息学竞赛就是这点好,有足够的时间和充足的资料(虽然大部分是英语的)可以自己去研究,而不是被别人牵着走
说实话我觉得凭兴趣和爱好去学习是一件很幸福的事,即使绕弯路,碰壁都会有收获,都会感到快乐

另外这道题还可以用BSGS水过去
虽然没有仔细看证明,有结论是答案不会超过\(6*p\)
然后大概就像这道题一样搞搞就好了

转载于:https://www.cnblogs.com/yicongli/p/9800705.html

求解斐波那契数列模$p$意义下最短循环节相关推荐

  1. 笔试题:一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。该题有三种解法:递归的方法求解斐波那契数列、用概率与统计的数学方法解决,3.动态规划

    笔试题 一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶.求该青蛙跳上一个 n 级的台阶总共有多少种跳法.该题有三种解法:1.递归的方法求解斐波那契数列.2.用概率与统计的数学方法解决,3.动态规划 ...

  2. 求解斐波那契数列(Fibonacci Numbers)算法居然有9种,你知道哪几种吗?

    By LongLuo 斐波那契数列(Fibonacci sequence),又称黄金分割数列,因数学家莱昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为&q ...

  3. 10_求解斐波那契数列

    求解斐波那契数列 题目一 写一个函数,输入 n ,求斐波那契(Fibonacci)数列的第 n 项.斐波那契数列的定义如下: F(0) = 0, F(1) = 1 F(N) = F(N - 1) + ...

  4. C语言实现求解斐波那契数列的四种方法及优化处理(递归,迭代,特殊性质公式,矩阵快速幂)

    众所周知,斐波那契数列是非常经典的一个数列,它的数学公式如下 为了便于观察,我们列出它的几项:0  1  1  2  3  5  8  13  21...... 下面我们将介绍四种方法来用C语言计算机 ...

  5. 斐波那契递归调用次数_递归求解斐波那契数列的时间复杂度——几种简洁证明...

    TL:DR: 暴力递归求解斐波那契数列的时间复杂度的紧界不是 ,而是 . 本文将给出几个简洁证明 用最暴力的方法求解斐波那契数列,时间复杂度是多少?具体地说,就是求下面这个程序的复杂度: def fi ...

  6. 用数学公式算法求解斐波那契数列

    目录 用数学公式算法求解斐波那契数列 程序设计 程序分析 用数学公式算法求解斐波那契数列 [问题描述]给定n,n小于90,打印出前n+1个斐波那契数.从第0个开始,即F(0)=0

  7. 求解斐波那契数列复杂度分析

    前言:斐波那契作为一个算法基础知识,大家一定要掌握,祝大家学得开心~ 什么是斐波那契数列(Fibonacci sequence)? 斐波那契数列(Fibonacci sequence),又称黄金分割数 ...

  8. python一只青蛙一次可以_40.细说递归之二:Python求解斐波那契数列

    本篇通过青蛙跳台阶.兔子数列(斐波那契数列)问题进一步理解递归思想的魅力. 上一篇最后的题目如下: 一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶.求该青蛙跳上一个n级的台阶总共有多少种跳法? 归纳 ...

  9. 快速幂求解斐波那契数列

    斐波那契数列 斐波那契数列是很经典也很简单的一条题目.其满足: F n = { 1 ( n ≤ 2 ) F n − 1 + F n − 2 ( n ≥ 3 ) F_{n}= \begin{cases} ...

最新文章

  1. ## Spark学习之路(一)
  2. SAP RETAIL 使用事务代码MM41创建商品主数据时不能激活检验类型?
  3. 《编译原理》课程教学大纲
  4. STM32F407的硬件I2C
  5. C语言程序设计现代方法1,2,3章
  6. cesium(鼠标事件)
  7. React、Angular、Vue 框架比较
  8. Hyperledger Fabric服务器配置及修改Docker容器卷宗存储根目录/位置
  9. Google 发布其非 Linux 系操作系统 Fuchsia 说明书!
  10. System.Web.AspNetHostingPermission 类型的权限已失败
  11. Matplotlib模块的使用
  12. 通过表名导出DDL语句(包含建表、索引、注释、主键)
  13. epoll文件服务器,使用epoll模型的服务器
  14. DDS产生双频正弦波及叠加
  15. 谈个人价值观与企业价值观(2014年收官之作,值得深思)
  16. java判断生肖_Java写出生肖年判断
  17. 存储-对象存储、文件存储和块存储
  18. 如何在Fcpx中卸载安装效果,标题,转场等FCPX模板插件
  19. 解决MySQL5和8的成绩排序问题
  20. 管理之黄金圈理论:让自己更值钱的5个能力

热门文章

  1. 组装k39小钢炮(ubuntu16.04),了解一下!
  2. 揭秘经典案例炼成之道 微信开发者大会精华回顾
  3. 信捷PLC中Y0用C语言怎么表示,信捷PLC
  4. DL在地球物理中的应用及发展趋势
  5. 智能家居第一步: WiFi 设备怎么连上网
  6. Linux下通过NetLink获取网口信息
  7. Android消息机制(Handler机制) - 线程的等待和唤醒
  8. 爱思助手苹果服务器调整,爱思助手怎么改虚拟位置 爱思助手改虚拟位置方法...
  9. Halcon入门教程手册
  10. 视频中地点位置标题文字标记介绍动画AE字幕模板