斐波那契数列的通项:

\[\frac{1}{\sqrt{5}}((\frac{1+\sqrt{5}}{2})-(\frac{1-\sqrt{5}}{2}))
\]

设T=\(\sqrt{5}*N\),\(y=\frac{\sqrt{5}+1}{2}\)

原式可化为\(y^n-(-\frac{1}{y}^n) \equiv T(mod\ p)\)

我们设\(t=y^n\)

原式可继续化为\(t-T*t \equiv (-1)^n(mod\ p)\)

然后我们对n进行奇偶讨论。

即分别求出\(t-T*t\equiv 1(mod\ p)\)和\(t-T*t\equiv -1(mod\ p)\)的t的解,这个用求根公式+二次剩余求出。

最后离散对数求出n。

(我写的时候求根公式背错了调了半个小时。。)

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<ctime>
using namespace std;
#define int long long
const int p=1e9+9;
const int N=201000;
int head[N],cnt;
int num,ans[10],w;
struct edge{
int w,id,nxt;
}e[N];
void add(int u,int w,int id){
for(int i=head[u];i;i=e[i].nxt)
if(e[i].w==w&&e[i].id<id)swap(e[i].id,id);
cnt++;
e[cnt].nxt=head[u];
e[cnt].w=w;
e[cnt].id=id;
head[u]=cnt;
}
struct comple{
int x,y;
comple (int xx=0,int yy=0){
x=xx;y=yy;
}
};
comple operator *(comple a,comple b){
return comple(((a.x*b.x%p+a.y*b.y%p*w%p)%p+p)%p,((a.x*b.y%p+a.y*b.x%p)%p+p)%p);
}
int random(int x){
return rand()*rand()%p;
}
int ksm(int x,int b){
int tmp=1;
while(b){
if(b&1)tmp=tmp*x%p;
x=x*x%p;
b>>=1;
}
return tmp;
}
comple ksm(comple x,int b){
comple tmp(1,0);
while(b){
if(b&1)tmp=tmp*x;
x=x*x;
b>>=1;
}
return tmp;
}
int Sqrt(int x){
if(p==2)return x;
if(ksm(x,(p-1)/2)+1==p)return -1;
int a;
while(233){
a=random(p);
w=((a*a%p-x)%p+p)%p;
if(ksm(w,(p-1)/2)+1==p)break;
}
comple res(a,1);
comple ans(0,0);
ans=ksm(res,(p+1)/2);
return ans.x;
}
int BSGS(int a,int b){
int block=sqrt(p)+1;
int tmp=b;
for(int i=0;i<block;i++,tmp=tmp*a%p)add(tmp%200000+1,tmp,i);
a=ksm(a,block);
if(a==0)return b==0?1:-1;
tmp=1;
for(int i=0;i<=block;i++,tmp=tmp*a%p){
for(int j=head[tmp%200000+1];j;j=e[j].nxt)
if(e[j].w==tmp&&i*block-e[j].id>=0)return i*block-e[j].id;
}
return -1;
}
int read(){
int sum=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){sum=sum*10+ch-'0';ch=getchar();}
return sum*f;
}
signed main(){
srand(time(NULL));
int n=read()%p;
int a=Sqrt(5);
int T=a*n%p;
int y=(1+a)*ksm(2,p-2)%p;
int x1=Sqrt(T*T%p+4ll);
if(x1!=-1){
int t1=(T+x1)%p*ksm(2,p-2)%p;
int t2=((T-x1)%p+p)%p*ksm(2,p-2)%p;
int ans1=BSGS(y,t1);
cnt=0;memset(head,0,sizeof(head));
int ans2=BSGS(y,t2);
if(ans1!=-1)ans[++num]=ans1;
if(ans2!=-1)ans[++num]=ans2;
}
int x2=Sqrt(T*T%p-4);
if(x2!=-1){
int t1=(T+x2)%p*ksm(2,p-2)%p;
int t2=((T-x2)%p+p)%p*ksm(2,p-2)%p;
cnt=0;memset(head,0,sizeof(head));
int ans1=BSGS(y,t1);
cnt=0;memset(head,0,sizeof(head));
int ans2=BSGS(y,t2);
if(ans1!=-1)ans[++num]=ans1;
if(ans2!=-1)ans[++num]=ans2;
}
if(num==0)printf("-1");
else {
sort(ans+1,ans+1+num);
printf("%lld",ans[1]);
}
return 0;
}

BZOJ 5104 Fib数列(二次剩余+BSGS)的更多相关文章

  1. @bzoj - 5104@ Fib数列

    目录 @description@ @solution@ @accepted code@ @details@ @description@ Fib数列为1,1,2,3,5,8... 求在Mod10^9+9 ...

  2. 【BZOJ5104】Fib数列(BSGS,二次剩余)

    [BZOJ5104]Fib数列(BSGS,二次剩余) 题面 BZOJ 题解 首先求出斐波那契数列的通项: 令\(A=\frac{1+\sqrt 5}{2},B=\frac{1-\sqrt 5}{2}\ ...

  3. BZOJ5104 Fib数列 二次剩余、BSGS

    传送门 发现只有通项公式可以解决考虑通项公式 \(F_n = \frac{1}{\sqrt{5}}((\frac{1+\sqrt{5}}{2})^n - (\frac{1-\sqrt{5}}{2})^ ...

  4. bzoj5104 Fib数列(BSGS+二次剩余)

    快AFO了才第一次写二次剩余的题…… 显然应该将Fn写成通项公式(具体是什么写起来不方便而且大家也都知道),设t=((1+√5)/2)n,T=√5N,然后可以得到t-(-1)t/t=√5N,两边同时乘 ...

  5. FIB数列

    斐波那契级数除以N会出现循环,此周期称为皮萨诺周期. 下面给出证明 必然会出现循环 这是基于下面事实: 1. R(n+2)=F(n+2) mod P=(F(n+1)+F(n)) mod P=(F(n+ ...

  6. bzoj5104: Fib数列

    Description Fib数列为1,1,2,3,5,8... 求在Mod10^9+9的意义下,数字N在Fib数列中出现在哪个位置 无解输出-1 Input 一行,一个数字N,N < = 10 ...

  7. 动态规划之Fib数列类问题应用

    一,问题描述 有个小孩上楼梯,共有N阶楼梯,小孩一次可以上1阶,2阶或者3阶.走到N阶楼梯,一共有多少种走法? 二,问题分析 DP之自顶向下分析方式: 爬到第N阶楼梯,一共只有三种情况(全划分,加法原 ...

  8. UVaLive 3357 Pinary (Fib数列+递归)

    题意:求第 k 个不含前导 0 和连续 1 的二进制串. 析:1,10,100,101,1000,...很容易发现长度为 i 的二进制串的个数正好就是Fib数列的第 i 个数,因为第 i 个也有子问题 ...

  9. 【bzoj5118】Fib数列2 费马小定理+矩阵乘法

    题目描述 Fib定义为Fib(0)=0,Fib(1)=1,对于n≥2,Fib(n)=Fib(n-1)+Fib(n-2) 现给出N,求Fib(2^n). 输入 本题有多组数据.第一行一个整数T,表示数据 ...

随机推荐

  1. 记一次redis-cluster的切换

    # redis-cli -h 10.5.8.18 -c -p 8001 cluster nodes|grep master 6d2f817064a10631648f24f450a37237b3d53f ...

  2. hdu1542 矩形面积并(线段树+离散化+扫描线)

    题意: 给你n个矩形,输入每个矩形的左上角坐标和右下角坐标. 然后求矩形的总面积.(矩形可能相交). 题解: 前言: 先说说做这道题的感受: 刚看到这道题顿时就懵逼了,几何 烂的渣渣.后来从网上搜题解 ...

  3. Python笔记26----正则表达式匹配

    1.语法: 2.题目1:数据类型: 如果要选择 time 为2014-12-18那天的数据:采用正则化来处理 代码:   import re regex = re.compile(r'^2014-12 ...

  4. IOS - 6\7下UINavigationBar的颜色的方法改变 ——转载http://www.th7.cn/Program/IOS/201310/155057.shtml

    IOS7下设置UINavigationBar的颜色的方法已经改变(当然如果是用自定义图片的话请忽略---) 首先是区别iOS7和之前版本的方法如下: //如果是iOS7以前的话if (floor(NS ...

  5. js正则表达式注册页面表单验证

    可以这样校验 <html> <head> <meta http-equiv="Content-Type" content="text/htm ...

  6. 小程序--wepy省市区三级联动选择

    产品老哥对项目再一次进行关爱, 新增页面, 新增需求, 很完美........ 不多说, 记录一下新增东西中的省市区联动选择, (这里全国地区信息是在本地, 但不建议这么做, 因为js文件太大.. 建 ...

  7. [CTSC1999][网络流24题]补丁VS错误

    题目:洛谷P2761.vijos P1019.codevs1239.codevs2218. 题目大意:有n个错误,m个不同的补丁. 对于一个补丁,有两个不同的字符串描述.具体如下: 如果当前错误包含第 ...

  8. 决策树(Decision Trees)

    简介 决策树是一个预测模型,通过坐标数据进行多次分割,找出分界线,绘制决策树. 在机器学习中,决策树学习算法就是根据数据,使用计算机算法自动找出决策边界. 每一次分割代表一次决策,多次决策而形成决策树 ...

  9. STM32使用HAL库实现ADC单通道转换

    STM32的ADC转换还是很强大的,它具有多个通道选择,这里我就不细说,不了解的可以自行百度,这里只是选取单通道,实现ADC转换.在文章开始之前,我说一下数据左对齐跟右对齐的差别,以前一直糊里糊涂的, ...

  10. springboot项目封装为docker镜像

    1.本次镜像的基础镜像是:https://www.cnblogs.com/JoeyWong/p/9173265.html 2.将打包好的项目文件放在与Dockerfile同级的目录下 3.Docker ...