题解:P7325 [WC2021] 斐波那契

· · 题解

题解:P7325 [WC2021] 斐波那契

更好的阅读体验\ 题目传送门

题意简述

F_0 = aF_1 = bF_i = (F_{i-1} + F_{i-2}) \bmod mi \ge 2),求 \min\{p\} 使得 F_p = 0

规定

F_n = \left\{\begin{aligned} 0 \space (n \le 1)\\1 \space (n=1) \\ F_{n-1}+F_{n-2} \space (n\ge 2) \end{aligned}\right.

题中序列为 G

$a \perp b$ 为 $a$、$b$ 互质。 ## 题目思路 首先容易发现原问题等价于求 $\min\{n\}$ 使得 $aF_{n-1}+bF_n\equiv 0\pmod m$。 > 证明: > > 当 $n = 2$ 时:$G_2 = G_0 + G_1 = b = (F_0a + F_1b) \bmod m$。 > > 当 $n =3$ 时:$G_3 = G_1+ G_2 = a + b = (F_1a+F_2b) \bmod m$。 > > 设当 $n \le i$ 时 $F_n = aF_{n-1}+bF_n$ 成立。 > > 当 $n = i + 1$ 时:$G_{i + 1} = (G_i + G_{i - 1}) \bmod m = (aF_{i - 1} + bF_i+aF_{i - 2} + bF_{i - 1}) \bmod m = (aF_{i}+bF_{i-1})\bmod m$。 > > 故 $aF_{n-1}+bF_n\equiv G_n\pmod m$。 为了解决原题,考虑把推导出一个形如 $B\equiv A\pmod m$($A$ 为和 $a$、$b$、$m$ 有关的式子、$B$ 为和 $F$ 有关的式子)。 设 $d = (a, b, m)$、$a' = \frac{a}{d}$、$b'=\frac{b}{d}$、$m'=\frac{m}{d}$ 则 $a' F_{n-1}+b' F_n\equiv 0\pmod {m'}$。 > 证明: > > 若 $x \equiv y \pmod z$,设 $d=(x, z, y)$。 > > $\because x\bmod z = (\frac{x}{d}\bmod z)d$,$y\bmod z = (\frac{y}{d}\bmod z)d$,$x \equiv y \pmod z$。 > > $\therefore (\frac{x}{d}\bmod z)d \equiv (\frac{y}{d}\bmod z)d \pmod z$。 > > $\therefore \frac{x}{d} \equiv \frac{y}{d} \pmod {\frac{z}{d}}$。 因为 $F_n \perp F_{n - 1}\space(1)$,所以 $(F_n,m')=(a',m')=p\space(2)$、$(F_{n-1},m')=(b',m')=q\space(2)$。 > $F_n \perp F_{n - 1}\space(1)$ 证明: > > 当 $n=2$ 时:$F_2 = 1, F_1=1,F_1 \perp F_2$。 > > 当 $n=3$ 时:$F_3 = 2, F_2=1,F_3 \perp F_2$。 > > 设当 $n\le i$ 时 $F_n \perp F_{n - 1}$ 成立。 > > 当 $n = i + 1$ 时: > > 设 $d = (F_i,F_{i+1})$,则:$d \mid F_i$、$d\mid F_{i + 1}$。 > > $\because F_n = F_{n-1}+F_{n-2}$。 > > $\therefore d\mid (F_{i+1}-F_i)=F_{i-1}$。 > > $\therefore d=(F_{i-1},F_i)=1\Rightarrow F_{i + 1} \perp F_i$。 > > 故 $F_n \perp F_{n - 1}$。 > $(F_n,m')=(a',m')=p\space(2)$、$(F_{n-1},m')=(b',m')=q\space(2)$ 证明。 > > 设 $p=(F_n,m')$,则 $p\mid F_n$、$p\mid F_{n - 1}$。 > > 又 $\because a' F_{n-1}+b' F_n\equiv 0\pmod {m'} \Rightarrow a' F_{n-1}=km-b' F_n$。 > > $\therefore p\mid a'F_{n-1}$。 > > 又 $\because F_n \perp F_{n - 1}$,$p \perp F_n$。 > > $\therefore p\mid a'$。 > > 反之,设 $p'=(a',m')$ 可得 $p'\mid F_n$。 > > 综上 $(F_n,m')=(a',m')=p$,同理 $(F_{n-1},m')=(b',m')=q$。 $a' F_{n-1}+b' F_n\equiv 0\pmod {m'}$ 两边同时除以 $pq$ 得 $\frac{a'}{pq}F_{n-1}+\frac{b'}{pq} F_n\equiv 0\pmod {\frac{m'}{pq}}$。易证加号两边互质,移项可得 $-\frac{b'}{a'}\equiv \frac{F_{n-1}}{F_n}\pmod {\frac{m'}{pq}}$。 由于斐波那契数列在模 $m$ 意义下是有循环节的,我们可以先预处理,对于每个 $m'$,计算 $\frac{F_{n-1}}{F_n}\bmod \frac{m'}{pq}$、$p$、$q$,并存储三元组 $(p,q,\frac{Fn−1}{Fn} \bmod \frac{m′}{pq})$。对于每组询问的 $a$、$b$,计算 $d⁡$,并得到 $a′$、$b′$、$m′$。计算 $p$、$q$、$-\frac{b'}{a'}\bmod \frac{m'}{pq}$,在存储的三元组中查找是否存在对应的项。如果存在,则找到最小的 $n$ 使得满足条件,如果不存在,则输出 $−1$。 ## AC code ```cpp #include<bits/stdc++.h> #define int long long using namespace std; const int N = 200000; using PPIII = pair<pair<int, int>, int>; int n, m, a, b; map<PPIII, int> ck[N + 5]; void exgcd(int a, int b, int &x, int &y) { if (a == 1) { x = 1; y = 0; return ; } exgcd(b, a % b, y, x); y -= a / b * x; } //解方程 ax + by = 0 int inv(int x, int m) { int n, temp; exgcd(x, m, n, temp); return (n % m + m) % m; } //解同余方程求逆元 signed main() { ios::sync_with_stdio(false); cin.tie(nullptr); cin >> n >> m; for (int i = 2; i <= m; i ++ ) if (m % i == 0) { // 枚举 m' int x = 1, y = 0, s = 0; while (true) { // 枚举斐波那契数列 if (x != 0 && y != 0) { int dx = __gcd(x, i), dy = __gcd(y, i); int mp = i / dx / dy; int t = ((y / dy) * inv((x / dx), mp) % mp + mp) % mp; // 存储 if (!ck[i].count({{dx, dy}, t})) ck[i][{{dx, dy}, t}] = s; // 保存 } int t = x; x = y; y = (t + y) % i; // 计算下一对 if (x == 1 && y == 0) break; // 循环节 s ++ ; } } while(n -- ) { cin >> a >> b; b = (m - b) % m; if (a == 0) { cout << "0\n"; continue; } if(b == 0) { cout << "1\n"; continue; } // 特殊判断 int d = __gcd(__gcd(a, b), m), mp = m / d; a /= d; b /= d; int p = __gcd(a, mp), q = __gcd(b, mp), mpp = mp / p / q; a /= p, b /= q; int k = (a * inv(b, mpp) % mpp + mpp) % mpp; // 查询 if (ck[mp].count({{q, p}, k})) cout << ck[mp][{{q, p}, k}] << '\n'; else cout << "-1\n"; // 查询答案 } return 0; } ```