前言

数学符号约定

  1. \(a,b,p\):表示任意自然数。
  2. \(F_x\):表示广义斐波那契数列的第 \(x\) 项。
  3. \(f_x\):表示普通斐波那契数列的第 \(x\) 项.

如非特殊说明,将会按照上述约定书写符号。

题目分析

首先引入一条定理:

普通斐波那契数列在模 \(m\) 意义下纯循环,且循环节为 \(O(m)\)。

证明可以去看 wlzhouzhuan 的博客,碍于篇幅限制不多赘述。

然后我们定义 \(F_0 = a,\, F_1 = b\),则显然我们有:\(F_p = af_{p-1} + bf_{p}\),证明平凡,如果想不出来可以手玩一下试试。

此时,我们的目标是对于 \(a,b\) 求出 \(p\) 使其满足下式:

\[af_{p-1} + bf_p \equiv 0 \pmod {m}
\]

移项,得:

\[af_{p-1} \equiv -bf_p \pmod m
\]

此时,我们不妨令 \(t = -b\),则我们有:

\[af_{p-1} \equiv tf_p \pmod m
\]

观察上式,发现如果我们能将 \(f_{p-1}\) 和 \(t\) 分别移项,然后预处理 \(\dfrac {f_p}{f_{p-1}}\) 问题就十分的简单了,但是因为 \(m\) 不为质数(即两者不一定互质),故我们不能这么做。

然而,俗话说的好,没有条件就让我们创造条件,先考虑对原式化简,设 \(d = \gcd(a,t,m)\),则原式变为:

\[\frac{a}{d} f_{p-1} \equiv \frac{t}{d} f_p \pmod {\frac{m}{d}}
\]

如果我们想让 \(\dfrac td\) 在 \(\dfrac md\) 的情况具有逆元,则需要保证 \(\dfrac td \perp \dfrac md\),但是此时显然不一定成立,于是我们设 \(d' = \gcd(\dfrac td, \dfrac md)\),现在考虑同余式左侧应该如何除以 \(d'\)。思考 \(d'\) 此时是 \(\dfrac td\) 和 \(\dfrac md\) 的公共因子,因为 \(d\) 已经是 \(a,t,m\) 的最大公因数了,则此时 \(\dfrac ad,\dfrac td,\dfrac md\) 之间已经不存在公共因子了,若 \(d' \not \perp a\),则说明 \(\dfrac ad,\dfrac td,\dfrac md\) 之间还存在公共因子 \(d'\),与条件相悖,故 \(d' \perp a\)。

因为同余式左侧一定是 \(d'\) 的倍数(否则无法构成同余关系),故得证 \(d' \mid f_{p-1}\),换言之,就是 \(d'\) 一定会整除在 \(f_{p-1}\) 身上。于是式子变为:

\[\begin{aligned}
\frac{a}{d} \frac{f_{p-1}}{d'} \equiv \frac{t}{dd'} f_p \pmod {\frac{m}{dd'}}\\
\frac{a}{d} \left( \frac{t}{dd'}\right) ^ {-1} \frac {f_{p-1}}{d'} \equiv f_p \pmod {\frac{m}{dd'}}
\end{aligned}
\]

好,现在我们再考虑能否将 \(\dfrac {f_{p-1}}{d'}\) 移项过去,要移项则必须保证 \(\dfrac{f_{p-1}}{d'} \perp \dfrac{m}{dd'}\),因为斐波那契数列具有性质 \(f_{p-1} \perp f_{p}\),并且我们又要必须保证右侧应当为 \(\gcd(\dfrac{f_{p-1}}{d'},\dfrac{m}{dd'})\) 的倍数,自然此时 \(\gcd(\dfrac{f_{p-1}}{d'},\dfrac{m}{dd'}) = 1\),故存在逆元,可以进行移项。

于是我们可以预处理三元组 \(\left( d,d',\dfrac{f_p}{\dfrac{f_{p-1}}{d'}} \bmod {\dfrac{m}{dd'}} \right)\),并用一个 map 来维护它。但是复杂度就直接飙升到令人无法接受的 \(O((\sum_{d \mid m}\sum_{d' \mid d} 1 )\log m)\)。于是我们考虑探究其中的性质。

我们回过头来看原先所写的 \(d' \mid f_{p-1}\),发现如果分两步枚举 \(d'\) 是非常笨的,因为我们还有 \(d' \mid \dfrac md\),我们又有 \(\gcd(\dfrac{f_{p-1}}{d'},\dfrac{m}{dd'}) = 1\),于是显然我们此时的 \(d'\) 只能等于 \(\gcd(f_{p-1},\dfrac md)\),故只需要枚举 \(d\) 和 \(p\) 就可以得到全部的三元组,此时的时间复杂度是 \(O(\sigma (m) \log m)\) 的,因为渐近意义下 \(\sigma(m)\) 是等价于 \(m \log \log m\) 的(具体证明参见 chenxia25 - P7325,所以枚举部分的复杂度是 \(O(m\log\log m \log m)\) 的,总时间复杂度为 \(O((m\log\log m+n)\log m)\)

注意:

  • 若 \(f_{p-1}\) 和 \(f_p\) 等于 \(0\) 的时候我们的同余式就爆炸了,于是我们需要把这个特判掉。

代码实现

下面给出了关键部分的代码实现。

n=read();
m=read();
f[1] = 1;
for(int d = 1;d<m;++d){
if(m%d==0){
for(int p=2;p;++p){
f[p] = (f[p-2] + f[p-1]) % (m/d);
if(f[p-1] == 0 && f[p] == 1)
break;
if(!f[p-1] || !f[p])
continue;
int dd = __gcd(f[p-1],m/d);
int val = 1 * f[p] * inv(f[p-1]/dd,m/dd/d) % (m/dd/d);
if(!hashtable[make_tuple(d,dd,val)])
hashtable[make_tuple(d,dd,val)] = p;
}
}
}
for(int i=1;i<=n;i++){
a=read();
b=read();
if(a==0){
printf("0\n");
continue;
}
if(b==0){
printf("1\n");
continue;
}
b=(m-b)%m;
int d = __gcd(a,__gcd(b,m));
int dd = __gcd(b/d, m/d);
int val = 1ll * a / d * inv(b/d/dd,m/d/dd) % (m/d/dd);
int data = hashtable[make_tuple(d,dd,val)];
if(!data)
printf("-1\n");
else
printf("%lld\n",data);
}

题解 P7325的更多相关文章

  1. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  2. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  3. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  4. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

  5. 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解

    题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...

  6. 2016ACM青岛区域赛题解

    A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  7. poj1399 hoj1037 Direct Visibility 题解 (宽搜)

    http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...

  8. 网络流n题 题解

    学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...

  9. CF100965C题解..

    求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...

  10. JSOI2016R3 瞎BB题解

    题意请看absi大爷的blog http://absi2011.is-programmer.com/posts/200920.html http://absi2011.is-programmer.co ...

随机推荐

  1. Vue中 router与route的区别

    $route对象 该对象表示当前的路由信息,包含当前URL解析得到的信息.包含当前的路径,参数,query对象等.其常用方法如下所示: $route.path 字符串,对应当前路由的路径,总是解析为绝 ...

  2. quarkus依赖注入之二:bean的作用域

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 关于bean的作用域(scope) 官方资料:http ...

  3. BUUCTF-Youngter-drive 双线程的思考

    拿到后先upx脱壳,然后直接进 从上向下看 应该是输入 慢慢看 明显的加密 这个函数大概是个加密 但是这个sleep函数是什么鬼??? 以下将拓展些许有关"线程"的概念:    一 ...

  4. JS逆向实战21——某查查webpack密码加密

    声明 本文章中所有内容仅供学习交流,抓包内容.敏感网址.数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除! 网站 aHR0cHM6Ly ...

  5. 知识图谱(Knowledge Graph)- Neo4j 5.10.0 使用 - Python 操作

    数据基于: 知识图谱(Knowledge Graph)- Neo4j 5.10.0 使用 - CQL - 太极拳传承谱系表 这是一个非常简单的web应用程序,它使用我们的Movie图形数据集来提供列表 ...

  6. 数据可视化【原创】vue复合数字形式展示

    做数据可视化的时候,经常碰到需要很灵活的数字形式展示. 先上个效果图: 如图包括名称,数量,别名,单位,上升下降,环比等等的复合数据展示,并且需要支持样式灵活配置. 此组件包括2个模块,父容器组件bo ...

  7. Mybatis自动生成mapper和实体类

    准备工作:需要俩个jar包: (1)连接数据库的jar包:mysql-connector-java-5.1.16-bin.jar (2)实现需求的插件Generator:mybatis-generat ...

  8. ssh-keygen无回车生成公钥私钥对

    ssh-keygen无回车生成公钥私钥对 ssh-keygen -t rsa -N '' -f /root/.ssh/id_rsa -q -t: -N:是指密码为空: -f:id_rsa是指保存文件为 ...

  9. heygen模型接口 简单使用 java版

    HeyGen - AI Spokesperson Video Creator  官网地址 Create a video (heygen.com) api地址 简介: 公司最近对ai方面业务比较感兴趣了 ...

  10. CopyOnWriteArrayList 写时复制思想

    写时复制 conpyOnWrite容器即写时复制容器.往一个容器添加元素的时候,不直接往当前容器Object[]添加,而是先将当前容器Object[]进行Copy,复制出一个新的容器Object[] ...