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

题面

BZOJ

题解

首先求出斐波那契数列的通项:

令\(A=\frac{1+\sqrt 5}{2},B=\frac{1-\sqrt 5}{2}\),那么\(f[n]=\frac{1}{\sqrt 5}(A^n-B^n)\)。

然后有\(A=-\frac{1}{B}\),所以有:\(f[n]=\frac{1}{\sqrt 5}((-\frac{1}{B})^n-B^n)\)。

令\(x=B^n\),这里需要考虑一下\(n\)的奇偶性:

如果\(n\)是偶数,有:\(\sqrt 5 f[n]=\frac{1}{x}-x\),转成一元二次方程可以直接求解\(x\),然后再\(BSGS\)还原。

\(n\)是奇数类似。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
using namespace std;
#define MOD 1000000009
int fpow(int a,int b){int s=1;while(b){if(b&1)s=1ll*s*a%MOD;a=1ll*a*a%MOD;b>>=1;}return s;}
namespace SQRT
{
bool check(int n){return fpow(n,(MOD-1)>>1)==1;}
int w;struct Num{int a,b;};
Num operator*(Num a,Num b){return (Num){(1ll*a.a*b.a+1ll*a.b*b.b%MOD*w)%MOD,(1ll*a.a*b.b+1ll*a.b*b.a)%MOD};}
Num fpow(Num a,int b){Num s=(Num){1,0};while(b){if(b&1)s=s*a;a=a*a;b>>=1;}return s;}
int Sqrt(int n)
{
if(!check(n))return -1;
int a;do a=rand()%MOD;while(check((1ll*a*a+MOD-n)%MOD));
w=(1ll*a*a-n+MOD)%MOD;
return fpow((Num){a,1},(MOD+1)>>1).a;
}
}
namespace BSGS
{
map<int,int> M;
const int m=sqrt(MOD);
int BSGS(int x,int y)
{
M.clear();
for(int i=0,t=1;i<m;++i,t=1ll*t*x%MOD)M[1ll*y*t%MOD]=i;
for(int i=1,p=fpow(x,m),t=p;i<=m;++i,t=1ll*t*p%MOD)
if(M.find(t)!=M.end())
return i*m-M[t];
return 2e9;
}
}
int n,ans=2e9;
int main()
{
int sqrt5=SQRT::Sqrt(5);
scanf("%d",&n);
int A=MOD-1,B=(MOD-1ll*sqrt5*n%MOD)%MOD;
int d1=(1ll*B*B%MOD+MOD-4ll*A%MOD)%MOD;
int d2=(1ll*B*B%MOD+4ll*A%MOD)%MOD;
if(SQRT::check(d1))
{
int vd=SQRT::Sqrt(d1);
int x1=1ll*(0ll+MOD-B+vd)%MOD*fpow(A+A,MOD-2)%MOD;
int x2=1ll*(0ll+MOD-B+MOD-vd)%MOD*fpow(A+A,MOD-2)%MOD;
int beta=1ll*(1+MOD-sqrt5)*fpow(2,MOD-2)%MOD;
int n1=BSGS::BSGS(beta,x1);
int n2=BSGS::BSGS(beta,x2);
if(!(n1&1))ans=min(ans,n1);
if(!(n2&1))ans=min(ans,n2);
}
if(SQRT::check(d2))
{
int vd=SQRT::Sqrt(d2);
int x1=1ll*(0ll+MOD-B+vd)%MOD*fpow(A+A,MOD-2)%MOD;
int x2=1ll*(0ll+MOD-B+MOD-vd)%MOD*fpow(A+A,MOD-2)%MOD;
int beta=1ll*(1+MOD-sqrt5)*fpow(2,MOD-2)%MOD;
int n1=BSGS::BSGS(beta,x1);
int n2=BSGS::BSGS(beta,x2);
if(n1&1)ans=min(ans,n1);
if(n2&1)ans=min(ans,n2);
}
printf("%d\n",ans<MOD?ans:-1);
return 0;
}

【BZOJ5104】Fib数列(BSGS,二次剩余)的更多相关文章

  1. BZOJ5104 Fib数列(二次剩余+BSGS)

    5在1e9+9下有二次剩余,那么fib的通项公式就有用了. 已知Fn,求n.注意到[(1+√5)/2]·[(1-√5)/2]=-1,于是换元,设t=[(1+√5)/2]n,原式变为√5·Fn=t-(- ...

  2. bzoj5104: Fib数列

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

  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. BZOJ 5104 Fib数列(二次剩余+BSGS)

    斐波那契数列的通项: \[\frac{1}{\sqrt{5}}((\frac{1+\sqrt{5}}{2})-(\frac{1-\sqrt{5}}{2}))\] 设T=\(\sqrt{5}*N\),\ ...

  6. bzoj5118 Fib数列2 二次剩余+矩阵快速幂

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=5118 题解 这个题一看就是不可做的样子. 求斐波那契数列的第 \(n\) 项,\(n \leq ...

  7. BZOJ5118: Fib数列2(二次剩余)

    题意 题目链接 题目链接 一种做法是直接用欧拉降幂算出\(2^p \pmod{p - 1}\)然后矩阵快速幂. 但是今天学习了一下二次剩余,也可以用通项公式+二次剩余做. 就是我们猜想\(5\)在这个 ...

  8. @bzoj - 5104@ Fib数列

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

  9. FIB数列

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

随机推荐

  1. 深入理解Java对象

    深入理解Java对象(理清关系) 1.对象的创建过程: 所有创建过程如下所示: new 类名 根据new的参数在常量池中定位一个类的符号引用. 如果没有找到这个符号引用,说明类还没有被加载,则进行类的 ...

  2. DBCP连接池使用

    转载请注明原文地址https://www.cnblogs.com/ygj0930/p/11280475.html 一:引入jar包或添加依赖 1:jar包 2:maven依赖 <dependen ...

  3. [TCP/IP] TCP流和UDP数据报之间的区别

    TCP流和UDP数据报之间的区别 1.TCP本身是面向连接的协议,S和C之间要使用TCP,必须先建立连接,数据就在该连接上流动,可以是双向的,没有边界.所以叫数据流 ,占系统资源多 2.UDP不是面向 ...

  4. Linux-CentOS-Nginx安装

    原文转自 jerryhe326:https://www.cnblogs.com/jerrypro/p/7062101.html 一.安装准备 首先由于nginx的一些模块依赖一些lib库,所以在安装n ...

  5. Java后端面经总结:拿下蚂蚁金服美团头条 offer 秘诀

    笔者在面过 猿辅导,去哪儿,旷视, 陌陌,头条, 阿里, 快手, 美团, 腾讯之后,除了收获一大堆面试问题,还思考到如何成为面试官眼中的”爱技术,爱思考,靠谱,有潜力候选人的”一些”套路”. 面试问题 ...

  6. 源码解读:webdriver client的原理

    前言 又到年底了,群里很多朋友说要开始备战2020金三银四,其实,我建议是,如果你不是技术大牛,就不要去凑热闹. 其实,现在(11,12月份)就是最佳换工作的时候,因为很多人想等着拿了年终再走,虽然招 ...

  7. mwArray和cv::Mat转化函数 20170812

    不是新东西了,但是有必要专门把这两个函数拿出来记录一下. 需要注意的是,Mat2mwArry函数的输入Mat类型是 CV_8UC1,灰度图. 如果要传递多通道图像的话,需要先cv::split()成多 ...

  8. 04-人脸识别-triplets loss 的解释(转载)

    转载至: https://blog.csdn.net/tangwei2014/article/details/46788025 下面是内容: [前言] 最近,learning to rank 的思想逐 ...

  9. Excel-图表制作

    柱形图:通常使用柱形图比较数据间的数量关系 折线图:使用折线图来反映数据间的趋势关系 饼图:使用饼图来表示数据间的分配关系  对图表进行刷选 再图表设计下的快速布局可以选择各种样式 迷你图  对某列单 ...

  10. JAVA基础概念(一)

    一.JAVA标识符 标识符就是用于给 Java 程序中变量.类.方法等命名的符号.如图标黄部分: 使用标识符时,需要遵守几条规则: 1.  标识符可以由字母.数字.下划线(_).美元符($)组成,但不 ...