博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ 5104 Fib数列(二次剩余+BSGS)
阅读量:4594 次
发布时间:2019-06-09

本文共 2125 字,大约阅读时间需要 7 分钟。

斐波那契数列的通项:

\[\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
#include
#include
#include
#include
#include
#include
using namespace std;#define int long longconst 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
>=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
=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;}

转载于:https://www.cnblogs.com/Xu-daxia/p/10248092.html

你可能感兴趣的文章
html中的Session
查看>>
后台管理页面1
查看>>
Java并发编程--多线程中的join方法详解
查看>>
[skill] mmap / fwrite / write linux磁盘读写的分层结构
查看>>
SQL 学习笔记<二> INSERT, UPDATE, DELETE, SELECT
查看>>
百度API接口python3如何使用【人脸搜索示例】
查看>>
Python字符串、集合练习_密码校验
查看>>
Unity 协程使用指南
查看>>
POJ 3017 Cut the Sequence (单调队列优化DP)
查看>>
mysql 权限管理介绍
查看>>
文本处理sed常用操作
查看>>
msyql常用命令
查看>>
232用栈实现队列
查看>>
如何应对“改变现状”的失败"
查看>>
STM32 CRC32 ( Delphi )
查看>>
Mongodb Manual阅读笔记:MongoDB教程
查看>>
hadoop分布式部署
查看>>
统计代码执行时间,使用Stopwatch和UserProcessorTime的区别
查看>>
生产者消费者
查看>>
Contos 安装Tomcat
查看>>