BZOJ5104 Fib数列 二次剩余、BSGS
发现只有通项公式可以解决考虑通项公式
\(F_n = \frac{1}{\sqrt{5}}((\frac{1+\sqrt{5}}{2})^n - (\frac{1-\sqrt{5}}{2})^n) = a\)
注意到根据二次互反律,在\(\mod 10^9+9\)意义下\(5\)存在二次剩余,所以先把\(\sqrt{5}\)对应的值算出来(实际上是\(383001016\))。
那么原式变为了\((\frac{1+\sqrt{5}}{2})^n - (\frac{1-\sqrt{5}}{2})^n = \sqrt{5}a\),\(x^n-y^n=a\)的方程好像还是不会解TAT
观察上面式子可以发现:\(\frac{1-\sqrt{5}}{2} = -\frac{1}{\frac{1 + \sqrt{5}}{2}}\),所以设\(\frac{1 + \sqrt{5}}{2} = x\),那么原式变为\(x - \frac{(-1)^n}{x} = \sqrt{5}a\)。
按照\(n\)的奇偶性讨论,可以得到一个一元二次方程,使用求根公式求出方程的解。注意到在求根公式中还有一个求\(\sqrt{\Delta}\)的操作,这里还需要计算一次二次剩余,如果这里二次剩余无解,那么方程就是无解的,否则就存在两个解。
然后我们最后的问题就是解出\((\frac{1 + \sqrt{5}}{2})^n = t\)的最小的\(n\),同时需要满足\(n\)是奇数或者是偶数。这里我们同样使用BSGS,只需要在分块的时候把块大小分成偶数,然后对于奇数和偶数分开考虑就可以了。
#include<bits/stdc++.h>
#include<tr1/unordered_map>
using namespace std;
using namespace std::tr1;
const int MOD = 1e9 + 9;
int val , g , sqrt5 , inv2;
int poww(long long a , int b){
int times = 1;
while(b){
if(b & 1) times = times * a % MOD;
a = a * a % MOD; b >>= 1;
}
return times;
}
struct BSGS{
unordered_map < int , int > odd , even , all;
int T , powbs;
void init(int base){
T = sqrt(MOD) + 1; if(T & 1) ++T;
powbs = poww(base , T);
int tms = 1;
for(int i = 0 ; i < T ; ++i , tms = 1ll * tms * base % MOD){
unordered_map < int , int > &now = i & 1 ? odd : even;
now[tms] = i; all[tms] = i;
}
}
int calc(int ans , int val){
unordered_map < int , int > &now = val == 0 ? all : (val == 1 ? odd : even);
int tms = 1ll * powbs * poww(ans , MOD - 2) % MOD;
for(int i = 1 ; i <= T ; ++i , tms = 1ll * tms * powbs % MOD)
if(now.find(tms) != now.end())
return i * T - now[tms];
return 2e9 + 1;
}
}A , B;
int findrt(){
int t = MOD - 1; vector < int > zys;
for(int i = 2 ; i * i <= t ; ++i)
if(t % i == 0){
zys.push_back(MOD / i);
while(t % i == 0) t /= i;
}
if(t - 1) zys.push_back(MOD / t);
for(int i = 2 ; ; ++i){
bool flg = 1;
for(int j = 0 ; j < zys.size() && flg ; ++j)
if(poww(i , zys[j]) == 1) flg = 0;
if(flg) return i;
}
}
int main(){
cin >> val; g = findrt(); A.init(g); sqrt5 = poww(g , A.calc(5 , 0) / 2);
val = 1ll * val * sqrt5 % MOD; inv2 = poww(2 , MOD - 2);
B.init((1ll + sqrt5) * inv2 % MOD);
int t = A.calc((1ll * val * val + MOD - 4) % MOD , 0) , ans = 2e9 + 1;
if(t % 2 == 0){
int sqt = poww(g , t / 2) , ans1 = 1ll * (val + sqt) * inv2 % MOD , ans2 = 1ll * (val - sqt + MOD) * inv2 % MOD;
ans = min(B.calc(ans1 , 1) , B.calc(ans2 , 1));
}
t = A.calc((1ll * val * val + 4) % MOD , 0);
if(t % 2 == 0){
int sqt = poww(g , t / 2) , ans1 = 1ll * (val + sqt) * inv2 % MOD , ans2 = 1ll * (val - sqt + MOD) * inv2 % MOD;
ans = min(ans , min(B.calc(ans1 , 2) , B.calc(ans2 , 2)));
}
if(ans == 2e9 + 1) puts("-1");
else cout << ans;
return 0;
}
BZOJ5104 Fib数列 二次剩余、BSGS的更多相关文章
- bzoj5104 Fib数列(BSGS+二次剩余)
快AFO了才第一次写二次剩余的题…… 显然应该将Fn写成通项公式(具体是什么写起来不方便而且大家也都知道),设t=((1+√5)/2)n,T=√5N,然后可以得到t-(-1)t/t=√5N,两边同时乘 ...
- 【BZOJ5104】Fib数列(BSGS,二次剩余)
[BZOJ5104]Fib数列(BSGS,二次剩余) 题面 BZOJ 题解 首先求出斐波那契数列的通项: 令\(A=\frac{1+\sqrt 5}{2},B=\frac{1-\sqrt 5}{2}\ ...
- bzoj5104: Fib数列
Description Fib数列为1,1,2,3,5,8... 求在Mod10^9+9的意义下,数字N在Fib数列中出现在哪个位置 无解输出-1 Input 一行,一个数字N,N < = 10 ...
- BZOJ5104 Fib数列(二次剩余+BSGS)
5在1e9+9下有二次剩余,那么fib的通项公式就有用了. 已知Fn,求n.注意到[(1+√5)/2]·[(1-√5)/2]=-1,于是换元,设t=[(1+√5)/2]n,原式变为√5·Fn=t-(- ...
- @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+ ...
- 动态规划之Fib数列类问题应用
一,问题描述 有个小孩上楼梯,共有N阶楼梯,小孩一次可以上1阶,2阶或者3阶.走到N阶楼梯,一共有多少种走法? 二,问题分析 DP之自顶向下分析方式: 爬到第N阶楼梯,一共只有三种情况(全划分,加法原 ...
- UVaLive 3357 Pinary (Fib数列+递归)
题意:求第 k 个不含前导 0 和连续 1 的二进制串. 析:1,10,100,101,1000,...很容易发现长度为 i 的二进制串的个数正好就是Fib数列的第 i 个数,因为第 i 个也有子问题 ...
- 【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,表示数据 ...
随机推荐
- linux命令之------Chmod命令
Chmod命令 1)作用:linux和unix的文件调用权限分为三级:文件拥有者/群组/其他.利用chmod可以控制文件如何被他人所调用.(主要就是修改文件夹,文件的权限) 2)U表示该文件的拥有者, ...
- 洛谷P1854 花店橱窗布置
题目 DP,直接递推比记忆化搜索简单. 定义状态\(dp[i][j]\)为前i行最后一个选择第i行第j个数所得到最大值. 易得状态转移方程 \(dp[i][j]=max(dp[i-1][k]+a[i] ...
- Python题库系列分享一(17道)
1.1 到Python官方网站下载并安装Python解释器环境.1.2 到Anaconda官方网站下载并安装最新的Anaconda3开发环境.1.3 Python程序的__name__的作用是什 ...
- C++2.0新特性(六)——<Smart Pointer(智能指针)之shared_ptr>
Smart Pointer(智能指针)指的是一类指针,并不是单一某一个指针,它能知道自己被引用的个数以至于在最后一个引用消失时销毁它指向的对象,本文主要介绍C++2.0提供的新东西 一.Smart P ...
- vue+elementui搭建后台管理界面(6登录和菜单权限控制)
不同的权限对应不同的路由(菜单),同时侧边栏也根据权限异步生成,实现登录和鉴权思路如下: 登录:点击登录,服务器验证通过后返回一个 token ,然后存到 cookie,再根据 token 拉取用户权 ...
- javaagent使用指南
今天打算写一下 Javaagent,一开始我对它的概念也比较陌生,后来在别人口中听到 字节码插桩,bTrace,Arthas后面才逐渐了解到Java还提供了这么个工具. JVM启动前静态Instrum ...
- java单元测试之如何实现异步接口的测试案例
测试是软件发布的重要环节,单元测试在实际开发中是一种常用的测试方法,java单元测试主要用junit,最新是junit5,本人开发一般用junit4.因为单元测试能够在软件模块组合之前尽快发现问题,所 ...
- 堆排序Heapsort的Java和C代码
Heapsort排序思路 将整个数组看作一个二叉树heap, 下标0为堆顶层, 下标1, 2为次顶层, 然后每层就是"3,4,5,6", "7, 8, 9, 10, 11 ...
- 025_Excel知识汇总
一.Excel相对引用和绝对应用的区别 加上了绝对地址符“$”的列标和行号为绝对地址,在公式向旁边复制时不会发生变化,没有加上绝对地址符号的列标和行号为相对地址,在公式向旁边复制时会跟着发生变化. 具 ...
- cesharp 完美支持flash
直接上代码: cefSettings.CefCommandLineArgs.Add("enable-npapi", "1"); //cefSettings.Ce ...