HDU3977(斐波那契数列模n的循环节长度)
题目: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的循环节长度)的更多相关文章
- HPU 1471:又是斐波那契数列??(大数取模)
		
1471: 又是斐波那契数列?? 时间限制: 1 Sec 内存限制: 128 MB 提交: 278 解决: 27 统计 题目描述 大家都知道斐波那契数列吧?斐波那契数列的定义是这样的: f0 = 0; ...
 - 2018年东北农业大学春季校赛 K wyh的数列【数论/斐波那契数列大数取模/循环节】
		
链接:https://www.nowcoder.com/acm/contest/93/K来源:牛客网 题目描述 wyh学长特别喜欢斐波那契数列,F(0)=0,F(1)=1,F(n)=F(n-1)+F( ...
 - HDU4549 M斐波那契数列 矩阵快速幂+欧拉函数+欧拉定理
		
M斐波那契数列 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Total Sub ...
 - HDU----(4549)M斐波那契数列(小费马引理+快速矩阵幂)
		
M斐波那契数列 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Total Sub ...
 - [HDU 4549] M斐波那契数列
		
M斐波那契数列 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Total Sub ...
 - [BSGS算法]纯水斐波那契数列
		
学弟在OJ上加了道"非水斐波那契数列",求斐波那契第n项对1,000,000,007取模的值,n<=10^15,随便水过后我决定加一道升级版,说是升级版,其实也没什么变化,只 ...
 - 斐波那契数列(NOIP1997)
		
题目链接:斐波那契数列 这题是数论的一个基本应用,还是很水,因为数据范围太水了,只有48,这也太小了.不过也有可能是当时的电脑速度跑得比较慢的原因.但是这个算法应该还是这个算法.主要思路就是递推求斐波 ...
 - M斐波那契数列(矩阵快速幂+费马小定理)
		
M斐波那契数列 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Total Sub ...
 - hdu 4549 M斐波那契数列 矩阵快速幂+欧拉定理
		
M斐波那契数列 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) Problem ...
 
随机推荐
- JQuery Ajax实例总结
			
jQuery确实是一个挺好的轻量级的JS框架,能帮助我们快速的开发JS应用,并在一定程度上改变了我们写JavaScript代码的习惯. 废话少说,直接进入正题,我们先来看一些简单的方法,这些方法都是对 ...
 - hdu 5014 思维题/推理
			
http://acm.hdu.edu.cn/showproblem.php?pid=5014 从小数開始模拟找方法规律,然后推广,尤其敢猜敢尝试,错了一种思路继续猜-----这是一种非常重要的方法啊 ...
 - fzu 1911 C. Construct a Matrix
			
C. Construct a Matrix Time Limit: 1000ms Case Time Limit: 1000ms Memory Limit: 32768KB Special Judge ...
 - RobotFramework  数据分离
			
RobotFramework 数据分离分为三种 1. Run 添加参数 2. 外部的Python文件 3. 读取Excel Run 添加参数 (适用于jenkins) 使用-v 参数名:参数值 使用外 ...
 - [WP8] Binding时,依照DataType来选择DataTemplate
			
原文 [WP8] Binding时,依照DataType来选择DataTemplate 范例下载 范例程序代码:点此下载 问题情景 在开发WPF.WP8...这类应用程序的时候,透过Binding机制 ...
 - Java 的垃圾回收机制(转)
			
先看一段转载,原文出自 http://jefferent.iteye.com/blog/1123677 虚拟机中的共划分为三个代:年轻代(Young Generation).年老点(Old Gener ...
 - poj 3211 Washing Clothes(背包)
			
很不错的01背包!!! 不过有点疑问!!!(注释) #include <algorithm> #include<stdio.h> #include<string.h> ...
 - WTL介绍
			
WTL简单介绍 关键词: WTL WTL是一个好东东.它开发的程序都很短小精悍.对开发WIN32的应用有很好的优点.它不用MFC开发.但可以高速产生窗体和控件. 以文本方式查看主题 - 温馨小筑 ...
 - maven的pom 提示错误 Failure to transfer com.thoughtworks.xstream:xstream:jar:
			
pom文件提示错误,信息如下 Description Resource Path Location TypeFailure to transfer com.thoughtwor ...
 - 学习android内核 -- 内存管理相关
			
Android内存管理: 1.当应用程序关闭以后,后台对应的进程并没有真正的退出(处于休眠状态,一般不占用系统CPU的资源),这是为了下次再启动的时候能快速启动. 2.当系统内存不够时,AmS会主动根 ...