题目: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. [置顶] Objective-C ,/,ios,/iphone开发基础:协议(protocol)

    protocol协议时为了补充Objective-C 只能单继承的缺陷而增加的一个新功能.Objective-C重所有的方法都是虚方法,所以在oc重也就没有关键字 virtual一说,有了协议可以补充 ...

  2. JQuery - 点击图片显示大图

    效果: 目录结构: 代码: <%@ Page Language="C#" AutoEventWireup="true" CodeFile="De ...

  3. c# 使用OracleParameter,同时使用replace函数

    也算不上是手误吧,这个问题竟然困扰了我那么多天,就是更新代码的时候,使用replace,但是oracle在.net下竟然是不支持汉字,所谓使用类似update x set y='m' where y= ...

  4. linux脚本初体验

    前言 第一次写linux脚本,有点紧张. 1. 写一个寻找特定用户的脚本文件? #! /bin/sh who | grep $1 其中脚本第一行用来告诉kernel去使用/bin/sh来解释这个脚本: ...

  5. perl .*?和.*

    redis01:/root# cat x2.pl my $str="212121a19823a456123"; if ($str =~/.*a(.*)23/){print &quo ...

  6. POJ 2186 Popular Cows (强联通)

    id=2186">http://poj.org/problem? id=2186 Popular Cows Time Limit: 2000MS   Memory Limit: 655 ...

  7. SetBkMode可设置文字背景色:TRANSPARENT或OPAQUE

    感受一下区别: procedure TForm1.Timer2Timer(Sender: TObject); var cvs: TCanvas; Rect: TRect; Str: string; b ...

  8. D7升级时候发现许多System函数和网络函数只有Byte版本的,需要注意

    SetLength 对于字符串,是WideChar的长度GetMem 只针对ByteMove 只针对ByteFillChar 只针对ByteWriteFile(API) 只针对Byte SetSock ...

  9. 【Demo 0009】表视图控制器

    本章学习要点:       1.  掌握表视图控制器结构;       2.  掌握表视图控制器的基本使用;       3.  掌握表视图表格的基本使用:       4.  掌握自定义表视图表格及 ...

  10. go之匿名字段

    struct,定义的时候是字段名与其类型一一对应,实际上Go支持只提供类型,而不写字段名的方式,也就是匿名字段,也称为嵌入字段. 当匿名字段是一个struct的时候,那么这个struct所拥有的全部字 ...