【codechef】FN/Fibonacci Number

时间:2023-02-08 02:21:21

题意

给出 c 和 P ,求最小的非负整数 n 使得 \(Fib(n)=c(mod~ P)\)

其中 P 是质数且 模 10 等于一个完全平方数(也就是说 P 的末位是个完全平方数,那么只能是 1 或者 9 )

(这里的 Fib 指的就是斐波那契数列)

前置芝士

  1. Cipolla (attack 巨巨写的炒鸡好,%%%)
  1. BSGS (Judge 菜鸡写的炒鸡烂,踩踩踩)

noteskey

不知道怎么做,只能黈力呢...

我们发现斐波那契数列第 n 项是:

\[{1\over \sqrt5}\Big(\big( { 1 +\sqrt 5 \over 2 }\big)^n-\big( {1-\sqrt 5 \over 2} \big)^n \Big)
\]

然后的话我们令 g 表示\(1\over \sqrt5\), q 表示 \({1+\sqrt5\over 2}\) , \(-{1\over q}\) 表示 \(1-\sqrt 5\over 2\) 了

这样的话原本的式子就是:

\[q^n-(-q)^{-n}=cg (mod\ P)
\]

令 \(x=q^n\) ,那么继续转式子:

\[x- {(-1)^{n}\over x}=cg (mod\ P)
\]

\[x^2- cgx -(-1)^{n}=0(mod\ P)
\]

然后的话我们就可以求根公式了:

\[x={-cg±\sqrt{(cg)^2+4(-1)^n}\over 2}
\]

这样我们就可以先假设 n 的奇偶性, \(Cipolla\) 求出根号里的东西然后中间的 正负号都取一遍,这样 x 的值已经固定了,然后我们 bsgs 求出满足当前枚举的奇偶性的 n ,答案就出来了呢(最小非负整数的话就四者取个 min 就好了呢)

上面还有一个问题: 5 万一不是 模 P 意义下的二次剩余怎么办...

这个问题不用担心,题目保证了 \(P\%10=1 ~~ or~~ 9\) ,也就是说 \(P\%5=± 1\) ,据说对于 \(P\%5=±1\) 的 P 都有** 5 是模 P 的二次剩余?** 不知道为什么 (【滑稽)的说...

总之我们套两个板子就可以 A 掉此题了 QWQ

code

虽说不晓得为什么 \(\omega\) 这个虚部当成向量的第二维默认为 1 个单位就是了

而且 \(BSGS\) 里面的 \(sqrt\) 我一开始写成 \(Sqrt\) 了呢,是不是没救了呢...

另外注意这里的 \(mod\) 范围 \(2e9\) ,\(inc\) 里面千万记得加上 \(0ll\) 不然可能要调很久...(和我一样)

//by Judge
#include<ctime>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#define Rg register
#define fp(i,a,b) for(Rg int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(Rg int i=(a),I=(b)-1;i>I;--i)
#define go(u) for(Rg int i=head[u],v=e[i].to;i;v=e[i=e[i].nxt].to)
#define ll long long
using namespace std;
const int inf=0x7fffffff;
const int M=1e5+3;
typedef int arr[M];
#ifndef Judge
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
#endif
char buf[1<<21],*p1=buf,*p2=buf;
inline void cmin(int& a,int b){a=a<b?a:b;}
inline int read(){ int x=0,f=1; char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
for(;isdigit(c);c=getchar()) x=x*10+c-'0'; return x*f;
} char sr[1<<21],z[20];int CCF=-1,Z;
inline void Ot(){fwrite(sr,1,CCF+1,stdout),CCF=-1;}
inline void print(int x,char chr='\n'){
if(CCF>1<<20)Ot();if(x<0)sr[++CCF]=45,x=-x;
while(z[++Z]=x%10+48,x/=10);
while(sr[++CCF]=z[Z],--Z);sr[++CCF]=chr;
} int c,s,p,w,a,mod,inv2,res,rt;
inline int dec(int x,int y){return x<y?x-y+mod:x-y;}
inline int inc(int x,int y){return 0ll+x+y>=mod?0ll+x+y-mod:x+y;}
inline int mul(int x,int y){return 1ll*x*y-1ll*x*y/mod*mod;}
inline int qpow(Rg int x,Rg int p,Rg int s=1){
for(;p;p>>=1,x=mul(x,x)) if(p&1) s=mul(s,x); return s;
}
struct cp{ int x,y; inline cp(Rg int xx,Rg int yy){x=xx,y=yy;}
inline cp operator *(const cp& b)const{ //有点鬼畜不知原理的向量乘操作呢
return cp(inc(mul(x,b.x),mul(w,mul(y,b.y))),inc(mul(x,b.y),mul(y,b.x)));
}
};
inline int qpow(Rg cp x,Rg int p){ Rg cp s(1,0); //向量快速乘?【逃
for(;p;p>>=1,x=x*x) if(p&1) s=s*x; return s.x;
}
inline int Sqrt(int x){ if(!x) return 0; // 0 的情况返回 0 就好了
if(qpow(x,(mod-1)>>1)==mod-1) return -1; // 无解返回 -1
while(1){ a=mul(rand(),rand()),w=dec(mul(a,a),x);
if(qpow(w,(mod-1)>>1)==mod-1) return qpow(cp(a,1),(mod+1)>>1);
}
}
const int N=262144;
struct Hash{ int pat,head[N]; struct Edge{int to,nxt,w; }e[N]; //hash 手打 map ?【雾
inline void clr(){memset(head,0,sizeof head),pat=0;}
inline void add(int v,int w){e[++pat]={v,head[v&262143],w},head[v&262143]=pat;}
inline int query(int x){go(x&262143)if(v==x)return e[i].w;return -1;}
}mp[2];
inline int bsgs(int x,int v,int tp){ //这里传的 tp 值是为了限制答案 n 的奇偶性
int m=sqrt(mod)+1; mp[0].clr(),mp[1].clr();
for(Rg int i=1,res=mul(v,x);i<=m;++i,res=mul(res,x)) mp[i&1].add(res,i);
for(Rg int i=1,tmp=qpow(x,m),res=tmp;i<=m;++i,res=mul(res,tmp))
if(mp[i*m&1^tp].query(res)!=-1) return i*m-mp[(i*m)&1^tp].query(res);
return inf;
}
int main(){ srand(time(NULL)); int T=read();
for(;T;--T){
c=read(),mod=read(),s=Sqrt(5),inv2=(mod+1)>>1;
p=mul(s+1,inv2),c=mul(c,s),res=inf; rt=Sqrt((1ll*c*c+4)%mod); //第一种可能
if(rt>=0) cmin(res,bsgs(p,mul(inc(c,rt),inv2),0)), //再来两种可能
cmin(res,bsgs(p,mul(dec(c,rt),inv2),0)); rt=Sqrt((1ll*c*c+mod-4)%mod); //第二种可能
if(rt>=0) cmin(res,bsgs(p,mul(inc(c,rt),inv2),1)), //然后又是两个可能
cmin(res,bsgs(p,mul(dec(c,rt),inv2),1));
print(res<inf?res:-1);
} return Ot(),0;
}

【codechef】FN/Fibonacci Number的更多相关文章

  1. 【leetcode】509&period; Fibonacci Number

    problem 509. Fibonacci Number solution1: 递归调用 class Solution { public: int fib(int N) { ) return N; ...

  2. 【LeetCode】509&period; Fibonacci Number 解题报告(C&plus;&plus;)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 动态规划 日期 题目地址:https://leetc ...

  3. 【转】oracle数据库NUMBER数据类型

    原文:http://www.jb51.net/article/37633.htm NUMBER ( precision, scale)a)  precision表示数字中的有效位;如果没有指定prec ...

  4. 【CF245H】Queries for Number of Palindromes(回文树)

    [CF245H]Queries for Number of Palindromes(回文树) 题面 洛谷 题解 回文树,很类似原来一道后缀自动机的题目 后缀自动机那道题 看到\(n\)的范围很小,但是 ...

  5. 【CodeChef】Querying on a Grid(分治,最短路)

    [CodeChef]Querying on a Grid(分治,最短路) 题面 Vjudge CodeChef 题解 考虑分治处理这个问题,每次取一个\(mid\),对于\(mid\)上的三个点构建最 ...

  6. 【CodeChef】Palindromeness(回文树)

    [CodeChef]Palindromeness(回文树) 题面 Vjudge CodeChef 中文版题面 题解 构建回文树,现在的问题就是要求出当前回文串节点的长度的一半的那个回文串所代表的节点 ...

  7. 【BZOJ4026】dC Loves Number Theory 分解质因数&plus;主席树

    [BZOJ4026]dC Loves Number Theory Description  dC 在秒了BZOJ 上所有的数论题后,感觉萌萌哒,想出了这么一道水题,来拯救日益枯竭的水题资源.    给 ...

  8. 【CodeChef】Find a special connected block - CONNECT(斯坦纳树)

    [CodeChef]Find a special connected block - CONNECT(斯坦纳树) 题面 Vjudge 题解 还是一样的套路题,把每个数字映射到\([0,K)\)的整数, ...

  9. 【LeetCode】375&period; Guess Number Higher or Lower II 解题报告(Python)

    [LeetCode]375. Guess Number Higher or Lower II 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://f ...

随机推荐

  1. Linux入门:运行级别解析

    Linux入门:运行级别解析   一.查看当前运行级别 Ubuntu中,runlevel命令 可以查看当前运行级别: CentOS中,who -r 命令查看当前运行级别:   www.2cto.com ...

  2. access violation at address General protection fault

    https://en.wikipedia.org/wiki/General_protection_fault In memory errors, the faulting program access ...

  3. 4&period;python中的用户交互

    学习完如何写'hello world'之后,我们还是不太满意,因为这样代码就写死了,以后运行的时候都只打印一局固定的话而已. 但是,我想在程序运行后,自己手动输入内容怎么办,此时就要学习如何使用用户交 ...

  4. GGS&colon; Sybase to Oracle

    Step 1: Start the GGSCI on Source and Target Source Target Oracle GoldenGate Command Interpreter for ...

  5. Android开发之AIDL的使用一--跨应用启动Service

    启动其他App的服务,跨进程启动服务. 与启动本应用的Service一样,使用startService(intent)方法 不同的是intent需要携带的内容不同,需要使用intent的setComp ...

  6. 数据库基本概念-oracle介绍

    甲骨文公司,全称甲骨文股份有限公司是全球最大的企业软件公司,总部位于美国加利福尼亚州的红木滩.甲骨文是继Microsoft及IBM后,全球收入第三多的软件公司.甲骨文公司1989年正式进入中国市场.重 ...

  7. OGEngine教程:声音载入

    以下介绍声音资源从载入到播放的一个流程 首先,我们将须要的音频文件放到assets文件夹下,OGE中SoundRes和MusicRes为我们封装了非常多经常使用的方法,能够用于载入及播放等经常使用功能 ...

  8. POJ 3737&sol;三分

    题目链接[http://poj.org/problem?id=3737] 题意:给出一个圆锥的表面积,求最大的体积,并输出最大体积的时候的圆锥的高度和底面积. 方法一: 根据定理:圆锥的表面积一定的时 ...

  9. AngularJS展示数据的ng-bind指令和&lbrace;&lbrace;&rcub;&rcub; 区别

    在AngularJS中显示模型中的数据有两种方式: 一种是使用花括号插值的方式: 1 <p>{{text}}</p> 另一种是使用基于属性的指令,叫做ng-bind: 1 &l ...

  10. Python使用xml&period;dom解析xml

    在菜鸟教程上找了个关于电影信息的xml类型的文档,用python内置的xml.dom来解析提取一下信息. 先复习一下xml概念: XML 指可扩展标记语言(EXtensible Markup Lang ...