P10663 BZOJ4833 最小公倍佩尔数 题解

P10663 BZOJ4833 最小公倍佩尔数 题解

这题还是有点意思的。

首先这个 \(e,f\) 看上去就有递推关系。略微拆一拆可以得到的是 \(e(n)=e(n-1)+2f(n-1),f(n)=e(n-1)+f(n-1)\)。再变换一下可以得到 \(e(n-1)=f(n)-f(n-1)\),那么带回去有 \(e(n)=f(n)+f(n-1)\),于是可以得到 \(f(n)=2f(n-1)+f(n-2)\)

现在考虑得到这个东西后有什么用。对于简单的递推式,考虑先构造出起转移矩阵,显然有:

\[\begin{bmatrix} f(n) &f(n-1) \end{bmatrix}= \begin{bmatrix} f(n-1) & f(n-2) \end{bmatrix} \begin{bmatrix} 2 &1 \\ 1 &0 \end{bmatrix} \]

考虑更普遍的形式:如果我们能从 \(f(n)\) 推知 \(f(n+m)\),那是有助于我们进一步发现性质的。显然有:\(\begin{bmatrix} f(n+m+1) &f(n+m) \end{bmatrix}=\begin{bmatrix} f(n+1)&f(n) \end{bmatrix}\begin{bmatrix} 2 & 1\\ 1 & 0 \end{bmatrix}^n\),由 \(f(1)=1,f(0)=0\),可以得到的是

\( \begin{bmatrix} 2 & 1 \\ 1 & 0 \end{bmatrix}=\begin{bmatrix} f(2) &f(1) \\ f(1) &f(0) \end{bmatrix}\),于是不难得到的是 \(\begin{bmatrix} 2 & 1\\ 1&0 \end{bmatrix}^n=\begin{bmatrix} f(n+1)&f(n) \\ f(n)&f(n-1) \end{bmatrix}\),那么会有:

\[\begin{aligned} \begin{bmatrix} f(n+m+1) &f(m) \end{bmatrix}&=\begin{bmatrix} f(n+1)&f(n) \end{bmatrix}\begin{bmatrix} f(m+1)&f(m) \\ f(m)&f(m-1) \end{bmatrix}\\&=\begin{bmatrix} f(n+1)f(m+1)+f(m)f(n) &f(n+1)f(m)+f(n)f(m-1) \end{bmatrix} \end{aligned} \]

值得一提的是这个东西在有系数的时候同样适用。然后题目要求的是和 \(\operatorname{lcm}\) 有关的东西,不妨先转化为和 \(\gcd\) 相关的性质。注意到 \(\gcd(f(n+m),f(n))=\gcd(f(n+1)f(m)+f(n)f(m-1),f(n))=\gcd(f(n+1)f(m),f(n))\),而由 \(\gcd(f(1),f(2))=1\) 可以归纳得到的是 \(\gcd(f(n),f(n+1))=1\),那么会有 \(\gcd(f(n+m),f(n))=\gcd(f(m),f(n))\),用辗转相除法可以得到的是 \(\gcd(f(n+m),f(n))=\gcd(f(\gcd(n+m,n)),f(n))=f(\gcd(n+m,n))\)。换句话说就是:

\[\gcd(f(n),f(m))=f(\gcd(n,m)) \]

这个性质就比较有用了。考虑到要求的是 \(\operatorname{lcm}\),那么由 \(\min-\max\) 容斥,有结论:

\[\operatorname{lcm}(S)=\prod_{T\subseteq S,T\neq\varnothing}\gcd(T)^{(-1)^{|T|+1}} \]

那么由上面的性质有 \(\gcd(f(i))=f(\gcd(T))(i\in T)\)。这样一来有:

\[\begin{aligned} g(n)&=\prod_{T\subseteq U,T\neq\varnothing}f(\gcd(T))^{(-1)^{|T|+1}}\\&= \prod_{i=1}^n f(i)^{\sum_{T\subseteq U,T\neq\varnothing}(-1)^{|T|+1}[\gcd(T)=i]} \end{aligned} \]

于是现在的核心问题是求出来 \(\sum_{T\subseteq U,T\neq\varnothing}(-1)^{|T|+1}[\gcd(T)=i]\) 这坨东西,考虑用莫比乌斯反演求解这类问题。

\(h(i)=\sum_{T\subseteq U,T\neq\varnothing}(-1)^{|T|+1}[\gcd(T)=i]\)\(H(i)=\sum_{i\mid d}h(d)\)。那么有

\[h(i)=\sum_{i\mid d}\mu(\frac di)H(i) \]

现在考虑 \(H(i)\) 如何求解。考虑写出 \(i\) 所有的倍数作为集合 \(P\),那么 \(T\) 的选择在 \(P\)\(|T|\) 为奇数和偶数的的大小应该一样。然而 \(T\neq\varnothing\),因此有一个奇数的情形会多出来,换句话说 \(H(i)=1\)

那么 \(h(i)=\sum_{i\mid d}\mu(\frac di)\),则 \(g(n)=\prod_{i=1}^nf(i)^{\sum_{i\mid d}\mu(\frac di)}=\prod_{d=1}^n\prod_{i\mid d}f(i)^{\mu(\frac di)}\)

直接求就可以了。

代码:

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e6 + 2;
int T;
int n, p;
int qpow(int x, int y) {
	int ans = 1;
	while (y) {
		if (y & 1) ans = ans *x % p;
		x = x * x % p;
		y >>= 1;
	}
	return ans;
}
int f[N], mu[N], ans[N];

signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	mu[1] = 1;
	for (int i = 1; i < N; i++)
		for (int j = 2; i * j < N; j++)
			mu[i * j] -= mu[i];
	cin >> T;
	while (T--) {
		cin >> n >> p;
		f[1] = 1;
		for (int i = 2; i <= n; i++) f[i] = (2 * f[i - 1] % p + f[i - 2]) % p;
		fill(ans, ans + n + 1, 1);
		for (int i = 1; i <= n; i++) {
			int inv = qpow(f[i], p - 2);
			for (int j = 1; i * j <= n; j++) {
				if (mu[j] == 1) ans[i * j] = ans[i * j] * f[i] % p;
				if (mu[j] == -1) ans[i * j] = ans[i * j] * inv % p;
			}
		}
		int res = 0, sm = 1;
		for (int i = 1; i <= n; i++) {
			sm = sm * ans[i] % p;
			res = (res + sm * i % p) % p;
		}
		cout << res << '\n';
	}
	return 0;
}
posted @ 2025-04-15 17:53  长安19路  阅读(13)  评论(0)    收藏  举报