题目: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. boost::asio async_write也不能保证一次发完所有数据 一

    你要是看过basic_stream_socket的文档,里面提到async_write_some不能保证将所有要发送的数据都发出去.并且提到如果想这样做,需要使用boost asio的async_wr ...

  2. Spring MVC Controller与jquery ajax请求处理json

    在用 spring mvc 写应用的时候发现jquery传递的[json数组对象]参数后台接收不到,多订单的处理,ajax请求: "}]}]} $.ajax({ url : url, typ ...

  3. HDU 4293 Groups

    模型挺好的dp题,其实这道题就是建一个模型然后就很容易想到递推过程了,我们可以把每个人的描述,存到数组a中,a[l][r]表示左边有l个,到第r个这个人所在一层停止...然后就可以写出转移状态方程了. ...

  4. hdu 5138

    参考……!!!! #include <iostream> #include <cstdio> #include <cmath> #include <cstri ...

  5. C语言深度解剖读书笔记(6.函数的核心)

    对于本节的函数内容其实就没什么难点了,但是对于函数这节又涉及到了顺序点的问题,我觉得可以还是忽略吧. 本节知识点: 1.函数中的顺序点:f(k,k++);  这样的问题大多跟编译器有关,不要去刻意追求 ...

  6. Redis intset

    Redis intset也非常简单.它是一个有序整数集合,实际上是一个有序数组,查找时二分查找,添加时可能需要内存挪动.唯一不同的是,它的整数类型是变动的,可以支持int16,int32,int64三 ...

  7. eclipse Maven plugin 配置

    1. eclipse -> help -> marketpalce -> search 在输入框中输入Maven,回车. 在搜索结果列表中往下拉几个安装 Maven Integrat ...

  8. tsunami:一种基于UDP协议的高速传输

    一. 需求 近期在做数据库迁移.常常须要打包实例传输.传统scp感觉非常慢. 二. 软件信息 1. 软件主页:http://tsunami-udp.sf.net/ 2. 软件安装:直接源代码make ...

  9. VK Cup 2012 Qualification Round 1---C. Cd and pwd commands

    Cd and pwd commands time limit per test 3 seconds memory limit per test 256 megabytes input standard ...

  10. iOS高效开源类库

    因为iOS SDK相对比较底层,所以开发者就得受累多做一些体力活.不过幸运的是,有很多第三方的类库可以用来简化很多不必要的工作.笔者整理了一下在本人学习过程中用到的一些比较有用Objective-C开 ...