设 f f f 为斐波那契函数,求
∏ i = 1 n ∏ j = 1 m f gcd ( i , j ) \prod_{i=1}^n\prod_{j=1}^mf_{\gcd(i,j)} i=1∏nj=1∏mfgcd(i,j)
推柿子:
设 n ≤ m n\leq m n≤m。
∏ i = 1 n ∏ j = 1 m f gcd ( i , j ) \prod_{i=1}^n\prod_{j=1}^mf_{\gcd(i,j)} ∏i=1n∏j=1mfgcd(i,j)
= ∏ d = 1 n f ( d ) ∏ i = 1 [ n d ] ∏ j = 1 [ m d ] [ gcd ( i , j ) = 1 ] =\prod_{d=1}^n f(d)\prod_{i=1}^{[\frac{n}{d}]}\prod_{j=1}^{[\frac{m}{d}]}[\gcd(i,j)=1] =∏d=1nf(d)∏i=1[dn]∏j=1[dm][gcd(i,j)=1]
= ∏ d = 1 n f ( d ) ∑ i = 1 [ n d ] ∑ j = 1 [ m d ] [ gcd ( i , j ) = 1 ] =\prod_{d=1}^n f(d)^{\sum\limits_{i=1}^{[\frac{n}{d}]}\sum\limits_{j=1}^{[\frac{m}{d}]}[\gcd(i,j)=1]} =∏d=1nf(d)i=1∑[dn]j=1∑[dm][gcd(i,j)=1]
= ∏ d = 1 n f ( d ) ∑ i = 1 [ n d ] [ n i d ] [ m i d ] μ ( i ) =\prod_{d=1}^n f(d)^{\sum\limits_{i=1}^{[\frac{n}{d}]}[\frac{n}{id}][\frac{m}{id}]\mu(i)} =∏d=1nf(d)i=1∑[dn][idn][idm]μ(i)
= ∏ T = 1 n ∏ d ∣ T f ( d ) [ n T ] [ m T ] μ ( T d ) =\prod_{T=1}^n\prod_{d|T}f(d)^{[\frac{n}{T}][\frac{m}{T}]\mu(\frac{T}{d})} =∏T=1n∏d∣Tf(d)[Tn][Tm]μ(dT)
= ∏ T = 1 n [ n T ] [ m T ] ∏ d ∣ T f ( d ) μ ( T d ) \boxed{=\prod_{T=1}^n[\frac{n}{T}][\frac{m}{T}]\prod_{d|T}f(d)\mu(\frac{T}{d})} =T=1∏n[Tn][Tm]d∣T∏f(d)μ(dT)
前半部分数论分块,后半部分预处理。
预处理一个数组 F F F, F k = ∏ i = 1 k ∏ x ∣ i f ( x ) μ ( i x ) F_k=\prod_{i=1}^k\prod_{x|i}f(x)\mu(\frac{i}{x}) Fk=∏i=1k∏x∣if(x)μ(xi)。
CODE:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
#define rep(i, a, b) for(int i = a; i <= b; ++i)
const int mod = 1e9 + 7;
const int maxn = 1e6 + 5;
const int N = 1e6;
int T, n, m;
bool vis[maxn];
int tot, f[maxn], F[maxn], inv[maxn], prm[maxn], mu[maxn];
inline int power(int x, int p)
{
int res = 1;
while(p > 0)
{
if(p & 1)
res = 1ll * res * x % mod;
p /= 2, x = 1ll * x * x % mod;
}
return res;
}
inline void pre()
{
F[0] = F[1] = mu[1] = f[1] = inv[1] = vis[1] = 1;
rep(i, 2, N)
{
f[i] = (f[i - 1] + f[i - 2]) % mod;
F[i] = 1, inv[i] = power(f[i], mod - 2);
if(!vis[i]) mu[i] = -1, prm[++tot] = i;
rep(j, 1, tot)
{
if(i * prm[j] > N) break;
vis[i * prm[j]] = 1;
if(i % prm[j] == 0) break;
mu[i * prm[j]] = -mu[i];
}
}
rep(i, 1, N) if(mu[i])
for(int j = i; j <= N; j += i)
F[j] = 1ll * F[j] * (mu[i] == 1 ? f[j / i] : inv[j / i]) % mod;
rep(i, 2, N) F[i] = 1ll * F[i] * F[i - 1] % mod;
}
int main()
{
pre();
scanf("%d", &T);
while(T--)
{
scanf("%d %d", &n, &m);
if(n > m) swap(n, m);
int ans = 1;
for(int l = 1, r; l <= n; l = r + 1)
{
r = min(n / (n / l), m / (m / l));
int k = 1ll * F[r] * power(F[l - 1], mod - 2) % mod;
ans = 1ll * ans * power(k, 1ll * (n / l) * (m / l) % (mod - 1)) % mod;
}
printf("%d\n", (ans + mod) % mod);
}
return 0;
}
—— E n d End End——