5在1e9+9下有二次剩余,那么fib的通项公式就有用了。

  已知Fn,求n。注意到[(1+√5)/2]·[(1-√5)/2]=-1,于是换元,设t=[(1+√5)/2]n,原式变为√5·Fn=t-(-1)n·t-1。同乘t并移项,可得t2-√5·Fn·t-(-1)n=0。讨论n的奇偶性,BSGS求二次剩余大力解方程即可。用BSGS求二次剩余是非常简单的,求出其以原根为底的离散对数即可。

  注意二次剩余有正负两解,但似乎代进去正根(即√gk=gk/2)就行了,不太明白。以及题目要求最小解,BSGS的时候注意顺序。还有BSGS不一定有解,我也不知道我在BSGS里面assert了半天是在干啥。调了一年惨炸了。

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cmath>
  4. #include<cstdlib>
  5. #include<cstring>
  6. #include<algorithm>
  7. #include<map>
  8. #include<cassert>
  9. using namespace std;
  10. #define ll long long
  11. #define P 1000000009
  12. char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<''||c>'')) c=getchar();return c;}
  13. int gcd(int n,int m){return m==?n:gcd(m,n%m);}
  14. int read()
  15. {
  16. int x=,f=;char c=getchar();
  17. while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
  18. while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
  19. return x*f;
  20. }
  21. int n,b,g,v,ans=P;
  22. map<int,int> f;
  23. int ksm(int a,int k)
  24. {
  25. int s=;
  26. for (;k;k>>=,a=1ll*a*a%P) if (k&) s=1ll*s*a%P;
  27. return s;
  28. }
  29. int inv(int a){return ksm(a,P-);}
  30. int BSGS(int g,int k)
  31. {
  32. f.clear();
  33. int block=sqrt(P),t=ksm(g,block),x=,ans=-;g=inv(g);
  34. for (int i=;i<block;i++)
  35. {
  36. if (f.find(1ll*x*k%P)==f.end()) f[1ll*x*k%P]=i;
  37. x=1ll*x*g%P;
  38. }
  39. x=;
  40. for (int i=;i<P;i+=block)
  41. {
  42. if (f.find(x)!=f.end()) {ans=f[x]+i;break;}
  43. x=1ll*x*t%P;
  44. }
  45. return ans;
  46. }
  47. int SQRT(int n)
  48. {
  49. int k=BSGS(g,n);
  50. if (k==-||k&) return -;
  51. return ksm(g,k>>);
  52. }
  53. void solve(int c,int op,int op2)
  54. {
  55. int delta=SQRT(((1ll*b*b-4ll*c)%P+P)%P);
  56. if (delta==-) return;
  57. delta=(P+op2*delta)%P;
  58. int ans1=1ll*((delta-b)%P+P)%P*inv()%P,ans2=1ll*((-delta-b)%P+P)*inv()%P;
  59. ans1=BSGS(v,ans1),ans2=BSGS(v,ans2);
  60. if ((ans1&)==op&&ans1>) ans=min(ans,ans1);
  61. if ((ans2&)==op&&ans2>) ans=min(ans,ans2);
  62. }
  63. int fib(int n)
  64. {
  65. struct matrix
  66. {
  67. int n,a[][];
  68. matrix operator *(const matrix&b) const
  69. {
  70. matrix c;c.n=n;memset(c.a,,sizeof(c.a));
  71. for (int i=;i<n;i++)
  72. for (int j=;j<;j++)
  73. for (int k=;k<;k++)
  74. c.a[i][j]=(c.a[i][j]+1ll*a[i][k]*b.a[k][j])%P;
  75. return c;
  76. }
  77. }f,a;
  78. f.n=;f.a[][]=,f.a[][]=;
  79. a.n=;a.a[][]=,a.a[][]=a.a[][]=a.a[][]=;
  80. for (;n;n>>=,a=a*a) if (n&) f=f*a;
  81. return f.a[][];
  82. }
  83. void work(int sqrt5)
  84. {
  85. b=(P-1ll*sqrt5*n%P)%P;
  86. v=1ll*(sqrt5+)*inv()%P;
  87. solve(P-,,),solve(,,);
  88. //solve(P-1,0,-1),solve(1,1,-1);
  89. }
  90. int main()
  91. {
  92. #ifndef ONLINE_JUDGE
  93. freopen("bzoj5104.in","r",stdin);
  94. freopen("bzoj5104.out","w",stdout);
  95. const char LL[]="%I64d\n";
  96. #else
  97. const char LL[]="%lld\n";
  98. #endif
  99. /*for (int i=2;;i++)
  100. {
  101. bool flag=1;
  102. for (int j=2;j*j<P;j++)
  103. if ((P-1)%j==0)
  104. {
  105. if (ksm(i,j)==1) {flag=0;break;}
  106. if (ksm(i,(P-1)/j)==1) {flag=0;break;}
  107. }
  108. if (flag) {g=i;break;}
  109. }*/
  110. g=;
  111. n=read();
  112. work(SQRT());//,work(P-SQRT(5));
  113. if (ans==P) cout<<-;else assert(fib(ans)==n),cout<<ans;
  114. return ;
  115. }

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

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

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

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

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

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

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

  4. bzoj5104: Fib数列

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

  5. @bzoj - 5104@ Fib数列

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

  6. FIB数列

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

  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. lastIndexOf()

    方法可返回一个指定的字符串值最后出现的位置,在一个字符串中的指定位置从后向前搜索.

  2. SpringBoot日记——实战篇——Url定向

    搞定了SpringBoot的一些基础核心的东西,我们需要实践一个项目来确认自己学习的东西能被应用,最初,我们会选择自己写一个登陆页面,这也是每个网站几乎都有的门面. 在写之前,还有一些知识点需要记录— ...

  3. django套用模板404报错小结

    首先,我的项目名是MyProject.每次当我运行,然后测试页面的时候,总是弹出 其实根据stackoverflow上某大佬的解释大意就是在setting.py和urls.py的匹配上出了问题 此处放 ...

  4. 详解YUV420数据格式

    原文地址:http://www.cnblogs.com/azraelly/archive/2013/01/01/2841269.html 1. YUV简介 YUV定义:分为三个分量,“Y”表示明亮度( ...

  5. Ubuntu下载磁力链接,torrent,迅雷链接

    用ubuntu下载电影:磁力链接,torrent,迅雷链接 需要软件:Ktorent, Amule 安装软件: sudo apt-get install ktorrent sudo apt-get i ...

  6. CentOS删除安装的程序

    以mysql举例: 首先查询安装包: rpm -qa|grep mysql 查询到的一个结果为:mysql-community-libs-5.7.13-1.el6.x86_64 yum 删除 yum ...

  7. vue 组件-父组件传值给子组件

    父组件通过属性,传值给子组件,子组件通过,props数组里的名称来接受父组件传过来的值. HTML部分: <div id="app"> <tmp1 :parent ...

  8. openstack系列文章(四)

    学习 openstack 的系列文章 - Nova Nova 基本概念 Nova 架构 openstack Log Nova 组件介绍 Nova 操作介绍 1. Nova 基本概念 Nova 是 op ...

  9. 工具 | Sublime

    Sublime 前言 妈耶..\(Sublime\)的界面真的是太好看啦哭哭.. 我永远喜欢Sublime! 强推Sublime... 正文 自从暑假用上的Ubontu 一开始用的是\(gedit\) ...

  10. go 运行项目

    此时运行项目,不能像之前简单的使用go run main.go,因为包main包含main.go和router.go的文件,因此需要运行go run *.go命令编译运行.如果是最终编译二进制项目,则 ...