题目:http://acm.hdu.edu.cn/showproblem.php?pid=3977

题意:求斐波那契数列模p的循环节长度,注意p最大是2*10^9,但是它的素因子小于10^6。

分析过程:首先我们知道fib数列模p如果出现了连续的1,0就意味这着开始循环了,因为接下来的项就是1 1 2 3 5等等。

那么很显然如果在第k位第一次出现了1,0,那么对于以后的1,0都可以表示为k*m。

那么,现在我们考虑如果fib数列模p在第pos位第一次出现了0,那么设0前面的那个数为a,则接下来的序列将是a,0,a,

a,2a,3a,5a,8a,....。可以看出a的系数就是一个fib数列,那么我们就可以得到fib(k+i)%p=a*fib(i)%p,其中i满

足0<i<k,所以进一步可以得到fib(i)=[a^j*fib(i-k*j)]%p。

那么我们现在先来说说如何求fib数模一个正整数n的循环节长度:

对于这个问题,我们先对n进行素因子分解,得到:,然后先对每一个形如p^k的数计算循环节,然后它们

的最小公倍数就是n的循环节长度(当然这里面涉及到CRT等等方面的基础)。那么现在问题就是计算p^k的循环节,这个问题

可以进一步简化成求G(p)*p^(k-1)。其中G(p)表示fib数列模素数p的循环节长度,所以现在的问题是如何求fib数列模一个

小于10^6的素数p的循环节长度。

求fib数列模p(p是素数)的最小循环节方法:

暴力枚举fib[i]%p==0的最小的i,然后记录pos=i+1,设a为fib[i]%p==0的前一位数,即a=fib[i-1]

那么我们知道fib数列模p的最小循环节长度一定是pos*x,那么也就是说现在要求一个最小的数x,满足,

求出x后,那么问题就解决了,剩下的就是合并等等。

#include <iostream>
#include <string.h>
#include <algorithm>
#include <stdio.h>
#include <math.h> using namespace std;
typedef long long LL;
const int N=1000005; bool prime[N];
int p[N];
int pri[N];
int num[N];
int f[N];
int fac[N];
int arr[N];
int k,cnt; void isprime()
{
k=0;
int i,j;
memset(prime,true,sizeof(prime));
for(i=2; i<N; i++)
{
if(prime[i])
{
p[k++]=i;
for(j=i+i; j<N; j+=i)
{
prime[j]=false;
}
}
}
} void Solve(LL n)
{
cnt=0;
int ct=0;
int t=(int)sqrt(n*1.0);
for(int i=0; p[i]<=t; i++)
{
if(n%p[i]==0)
{
ct=0;
pri[cnt]=p[i];
while(n%p[i]==0)
{
ct++;
n/=p[i];
}
num[cnt]=ct;
cnt++;
}
}
if(n>1)
{
pri[cnt]=n;
num[cnt]=1;
cnt++;
}
} LL gcd(LL a,LL b)
{
return b? gcd(b,a%b):a;
} LL quick_mod(LL a,LL b,LL m)
{
LL ans=1;
a%=m;
while(b)
{
if(b&1)
{
ans=ans*a%m;
b--;
}
b>>=1;
a=a*a%m;
}
return ans;
} int main()
{
isprime();
int T,a,pos,tt=1;
LL n;
cin>>T;
while(T--)
{
cin>>n;
printf("Case #%d: ",tt++);
Solve(n);
pos=0;
for(int k=0; k<cnt; k++)
{
f[0]=f[1]=1;
for(int i=2;; i++)
{
f[i]=(f[i-1]+f[i-2])%pri[k];
if(f[i]==0)
{
a=f[i-1];
pos=i+1;
break;
}
}
int cv=0;
int tmp=pri[k]-1;
int t=(int)sqrt(tmp*1.0);
for(int i=1; i<=t; i++)
{
if(tmp%i==0)
{
if(tmp/i==i)
fac[cv++]=i;
else
{
fac[cv++]=i;
fac[cv++]=tmp/i;
}
}
}
int record=0;
sort(fac,fac+cv);
for(int i=0; i<cv; i++)
{
if(quick_mod(a,fac[i],pri[k])==1)
{
record=fac[i];
break;
}
}
LL ans=record*pos;
for(int i=1; i<num[k]; i++)
ans*=pri[k];
arr[k]=ans;
}
LL ret=1;
for(int i=0; i<cnt; i++)
ret=ret/gcd(ret,arr[i])*arr[i];
cout<<ret<<endl;
}
return 0;
}

HDU3977(斐波那契数列模n的循环节长度)的更多相关文章

  1. HPU 1471:又是斐波那契数列??(大数取模)

    1471: 又是斐波那契数列?? 时间限制: 1 Sec 内存限制: 128 MB 提交: 278 解决: 27 统计 题目描述 大家都知道斐波那契数列吧?斐波那契数列的定义是这样的: f0 = 0; ...

  2. 2018年东北农业大学春季校赛 K wyh的数列【数论/斐波那契数列大数取模/循环节】

    链接:https://www.nowcoder.com/acm/contest/93/K来源:牛客网 题目描述 wyh学长特别喜欢斐波那契数列,F(0)=0,F(1)=1,F(n)=F(n-1)+F( ...

  3. HDU4549 M斐波那契数列 矩阵快速幂+欧拉函数+欧拉定理

    M斐波那契数列 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Sub ...

  4. HDU----(4549)M斐波那契数列(小费马引理+快速矩阵幂)

    M斐波那契数列 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Sub ...

  5. [HDU 4549] M斐波那契数列

    M斐波那契数列 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Sub ...

  6. [BSGS算法]纯水斐波那契数列

    学弟在OJ上加了道"非水斐波那契数列",求斐波那契第n项对1,000,000,007取模的值,n<=10^15,随便水过后我决定加一道升级版,说是升级版,其实也没什么变化,只 ...

  7. 斐波那契数列(NOIP1997)

    题目链接:斐波那契数列 这题是数论的一个基本应用,还是很水,因为数据范围太水了,只有48,这也太小了.不过也有可能是当时的电脑速度跑得比较慢的原因.但是这个算法应该还是这个算法.主要思路就是递推求斐波 ...

  8. M斐波那契数列(矩阵快速幂+费马小定理)

    M斐波那契数列 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Sub ...

  9. hdu 4549 M斐波那契数列 矩阵快速幂+欧拉定理

    M斐波那契数列 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Problem ...

随机推荐

  1. 【Cocos2d-X游戏实战开发】捕鱼达人之开发前准备工作(一)

    本系列学习教程使用的是cocos2d-x-2.1.4(最新版为cocos2d-x-2.1.5) 博主发现前两个系列的学习教程被严重抄袭,在这里呼吁大家请尊重开发者的劳动成果, 转载的时候请务必注明出处 ...

  2. Opencv实现图像的灰度处理,二值化,阀值选择

    前几天接触了图像的处理,发现用OPencv处理确实比較方便.毕竟是非常多东西都封装好的.可是要研究里面的东西,还是比較麻烦的,首先,你得知道图片处理的一些知识,比方腐蚀,膨胀,仿射,透射等,还有非常多 ...

  3. uploadify,实际开发案例【选择完文件点击上传才上传】

    <script type="text/javascript"> )+Math.floor(Math.random()*)+']-'; //设置随机文件前缀. $k(fu ...

  4. OCM读书笔记(2) - PL/SQL 基础

    1. % type 用法,提取% type所在字段的类型 declare     myid dept.deptno % type;    myname dept.dname % type;begin  ...

  5. 枚举类型互相转换(使用GetEnumName和TypeInfo两个函数)

    usesClasses,TypInfo ; typeTCommandType = (ctEmptyCommand,ctAdd,ctModify); TCommandTypeConvert=classp ...

  6. Java编码浅析(注意区分三个概念)(转)

    编码: (1)外部资源的字符集-----没有读入jvm中的数据都是外部资源 (2)jvm中数据的字符集-----都是unicode (1)和(2)之间发生交互时,如果不指定编码,则使用JVM平台默认字 ...

  7. 腾讯測试project师笔试面试记录

        从3月29日參加腾讯笔试開始,開始了为期1周的腾讯之旅,尽管最后还是跪在了二面上,可是感觉收获非常多,至少明确了自己与向往的BAT公司的差距,明确了自己还是路漫漫其修远兮.     腾讯非常注 ...

  8. QTableView 固定列宽度(鼠标拖动后,仍可固定)

    QTableView 提供一个函数: void QTableView::setColumnWidth ( int column, int width ) 用于设置column指定的列的宽度 但setC ...

  9. mvc action 有多种跳转

    在ASP.NET mvc下,action 有多种跳转方式: return RedirectToAction("Index");//一个参数时在本Controller下 如果Redi ...

  10. ural 1837. Isenbaev's Number bfs

    题目链接:http://acm.timus.ru/problem.aspx?space=1&num=1837 描述: Isenbaev是国外的一个大牛. 现在有许多人要参加ACM ICPC. ...