bzoj5104 Fib数列(BSGS+二次剩余)
快AFO了才第一次写二次剩余的题……
显然应该将Fn写成通项公式(具体是什么写起来不方便而且大家也都知道),设t=((1+√5)/2)n,T=√5N,然后可以得到t-(-1)t/t=√5N,两边同时乘t,移项,得到t2-√5Nt-(-1)n=0。分别讨论n是奇数或偶数的情况,通过求根公式求t,写个二次剩余即可。
#include<bits/stdc++.h>
using namespace std;
const int sq5=,inv2=5e8+,mod=1e9+,inf=0x7fffffff;
int n,w,ans=inf;
map<int,int>mp;
struct com{
int x,y;
com operator*(const com&a)
{return(com){(1ll*x*a.x+1ll*y*a.y%mod*w)%mod,(1ll*x*a.y+1ll*y*a.x)%mod};}
};
int qpow(int a,int b)
{
int ret=;
while(b)
{
if(b&)ret=1ll*ret*a%mod;
a=1ll*a*a%mod,b>>=;
}
return ret;
}
int Sqrt(int n)
{
if(qpow(n,mod/)!=)return ;
int a=;
while(qpow((1ll*a*a%mod-mod-n)%mod,mod/)==)a=rand();
com x=(com){a,mod-},ans=(com){,};
int y=inv2;
w=(1ll*a*a%mod+mod-n)%mod;
while(y)
{
if(y&)ans=ans*x;
x=x*x,y>>=;
}
return ans.x;
}
int BSGS(int t,int n)
{
int m=ceil(sqrt(mod)),inv=qpow(t,mod-),v=n;
mp.clear(),mp[n]=mod;
for(int i=;i<m;i++)v=1ll*v*inv%mod,mp[v]=mp[v]?mp[v]:i;
if(mp[])return mp[]%mod;
v=,t=qpow(t,m);
for(int i=;i<=m;i++)
{
v=1ll*v*t%mod;
if(mp[v])return(i*m+mp[v])%mod;
}
return -;
}
int main()
{
scanf("%d",&n);
int t=1ll*(sq5+)*inv2%mod,T=1ll*sq5*n%mod,ans=inf;
int r0=Sqrt(5ll*n*n%mod+),r1=Sqrt(5ll*n*n%mod-),x;
if(r0)
{
x=BSGS(t,1ll*(T+r0)*inv2%mod);
if(x>-&&x%==)ans=min(ans,x);
x=BSGS(t,1ll*(T+mod-r0)*inv2%mod);
if(x>-&&x%==)ans=min(ans,x);
}
if(r1)
{
x=BSGS(t,1ll*(T+r1)*inv2%mod);
if(x>-&&x%)ans=min(ans,x);
x=BSGS(t,1ll*(T+mod-r1)*inv2%mod);
if(x>-&&x%)ans=min(ans,x);
}
if(ans==inf)puts("-1");else printf("%d",ans);
}
bzoj5104 Fib数列(BSGS+二次剩余)的更多相关文章
- BZOJ5104 Fib数列(二次剩余+BSGS)
5在1e9+9下有二次剩余,那么fib的通项公式就有用了. 已知Fn,求n.注意到[(1+√5)/2]·[(1-√5)/2]=-1,于是换元,设t=[(1+√5)/2]n,原式变为√5·Fn=t-(- ...
- bzoj5104: Fib数列
Description Fib数列为1,1,2,3,5,8... 求在Mod10^9+9的意义下,数字N在Fib数列中出现在哪个位置 无解输出-1 Input 一行,一个数字N,N < = 10 ...
- BZOJ5104 Fib数列 二次剩余、BSGS
传送门 发现只有通项公式可以解决考虑通项公式 \(F_n = \frac{1}{\sqrt{5}}((\frac{1+\sqrt{5}}{2})^n - (\frac{1-\sqrt{5}}{2})^ ...
- BZOJ 5104 Fib数列(二次剩余+BSGS)
斐波那契数列的通项: \[\frac{1}{\sqrt{5}}((\frac{1+\sqrt{5}}{2})-(\frac{1-\sqrt{5}}{2}))\] 设T=\(\sqrt{5}*N\),\ ...
- bzoj5118 Fib数列2 二次剩余+矩阵快速幂
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=5118 题解 这个题一看就是不可做的样子. 求斐波那契数列的第 \(n\) 项,\(n \leq ...
- BZOJ5118: Fib数列2(二次剩余)
题意 题目链接 题目链接 一种做法是直接用欧拉降幂算出\(2^p \pmod{p - 1}\)然后矩阵快速幂. 但是今天学习了一下二次剩余,也可以用通项公式+二次剩余做. 就是我们猜想\(5\)在这个 ...
- 【BZOJ5104】Fib数列(BSGS,二次剩余)
[BZOJ5104]Fib数列(BSGS,二次剩余) 题面 BZOJ 题解 首先求出斐波那契数列的通项: 令\(A=\frac{1+\sqrt 5}{2},B=\frac{1-\sqrt 5}{2}\ ...
- @bzoj - 5104@ Fib数列
目录 @description@ @solution@ @accepted code@ @details@ @description@ Fib数列为1,1,2,3,5,8... 求在Mod10^9+9 ...
- FIB数列
斐波那契级数除以N会出现循环,此周期称为皮萨诺周期. 下面给出证明 必然会出现循环 这是基于下面事实: 1. R(n+2)=F(n+2) mod P=(F(n+1)+F(n)) mod P=(F(n+ ...
随机推荐
- Dijkstra--The Captain
*传送 给定平面上的n个点,定义(x1,y1)到(x2,y2)的费用为min(|x1-x2|,|y1-y2|),求从1号点走到n号点的最小费用. 先给一段证明:给定三个x值,x1<x2<x ...
- 关于ThinkCMF后台验证码不显示
最近小凯在群里看到好多同学们遇到一个头疼的问题,程序在本地调试好了之后上传服务器,后台的验证码就会不显示,今天三群的 [江苏 冰点零度 php] 同学遇到了这个问题. 开始小凯以为是GB库出来问题 ...
- 实验吧Web-难-头有点大(http头伪造:浏览器、国家、.Net framework版本)
进去网站显示: 此处告诉我们要干三件事: (1).net framework 版本为9.9 (2)告诉服务器我们的地址为英国 (3)我们访问站点用的是IE 下面我们就抓的包中伪造. 1:.net fr ...
- 吴裕雄--天生自然C++语言学习笔记:C++ 存储类
存储类定义 C++ 程序中变量/函数的范围(可见性)和生命周期.这些说明符放置在它们所修饰的类型之前.下面列出 C++ 程序中可用的存储类: auto register static extern m ...
- VUE常见的语法
模版渲染{{msg}} v-html="" v-text="" v-bind:id="" 类似 attr 三元判断 {{ok?'yes': ...
- POJ - 3665 iCow(模拟)
题意:有N首歌曲,播放的顺序按照一定的规则,输出前T首被播放的歌的编号.规则如下: 1.每首歌有一个初始的等级r,每次都会播放当前所有歌曲中r最大的那首歌(若r最大的有多首,则播放编号最小的那首歌). ...
- shell字典使用
1.shell界面或脚本中 pcode=(["10"]="BeiJing" ["22"]="TianJin") echo ...
- 正则表达式模式修正符 比如/esi
正则表达式模式修正符 比如/esi 作者: 字体:[增加 减小] 类型:转载 下面列出了当前在 PCRE 中可能使用的修正符.括号中是这些修正符的内部 PCRE 名.修正符中的空格和换行被忽略,其它字 ...
- vi粘贴代码后格式混乱的问题
最近在远程终端使用vi发现从其他地方复制代码的后,粘贴到vi里面出现格式变乱的问题. 主要是因为终端通常无法区分输入是来自用户输入还是来自粘贴,所以终端也不能通知 vim 输入来自何处.在 vim 里 ...
- 问:为什么java是单继承,但却是多实现的呢?
在学习的过程中,我发现了如题的这个有趣的问题. 单继承不必解释,一个类只能有一个直接父类:但是对于接口的实现,一个类却能够实现多个接口. 为什么是这种情况呢?我们来举个简单的栗子看一下: class ...