题面:bzoj4816
题意:求 ∏ i = 1 n ∏ j = 1 m f [ g c d ( i , j ) ] \prod _{i=1} ^n \prod _{j=1} ^m f[gcd (i, j)] ∏i=1n∏j=1mf[gcd(i,j)],其中 f [ i ] f[i] f[i]表示第 i i i项斐波那契数列。膜 1 0 9 + 7 10^9+7 109+7
题解:
a n s = ∏ i = 1 n ∏ j = 1 m f [ g c d ( i , j ) ] = ∏ d = 1 n ∏ i = 1 n ∏ j = 1 m [ g c d ( i , j ) = d ] f [ d ] = ∏ d = 1 n f [ d ] ∑ i = 1 n d ∑ j = 1 m d [ g c d ( i , j ) = 1 ] \begin {aligned} ans & = \prod _{i=1} ^n \prod _{j = 1} ^m f[gcd (i, j)] \\ &= \prod _{d = 1} ^n \prod _{i=1} ^n \prod _{j=1} ^m [gcd (i, j) = d] f[d] \\ & = \prod _{d = 1} ^n f[d] ^ {\sum _{i=1} ^{\frac n d} \sum _{j = 1} ^{\frac m d} [gcd (i, j) = 1]} \end {aligned} ans=i=1∏nj=1∏mf[gcd(i,j)]=d=1∏ni=1∏nj=1∏m[gcd(i,j)=d]f[d]=d=1∏nf[d]∑i=1dn∑j=1dm[gcd(i,j)=1]
指数上的那部分: ∑ i = 1 n d ∑ j = 1 m d [ g c d ( i , j ) = 1 ] = ∑ i = 1 n d μ ( i ) ⌊ n i d ⌋ ⌊ m i d ⌋ \sum _{i = 1} ^{\frac n d} \sum _{j = 1} ^{\frac m d} [gcd (i, j) = 1] = \sum _{i = 1} ^{\frac n d} \mu (i) \lfloor \frac n {id} \rfloor \lfloor \frac m {id} \rfloor ∑i=1dn∑j=1dm[gcd(i,j)=1]=∑i=1dnμ(i)⌊idn⌋⌊idm⌋
令 T = i d T = id T=id
∑ T = 1 n ⌊ n T ⌋ ⌊ m T ⌋ ∑ d ∣ T μ ( T d ) \sum _{T = 1} ^n \lfloor \frac n T \rfloor \lfloor \frac m T \rfloor \sum _{d \mid T} \mu (\frac T d) ∑T=1n⌊Tn⌋⌊Tm⌋∑d∣Tμ(dT)
代回得:
a n s = ∏ T = 1 n ∏ d ∣ T f [ d ] ⌊ n T ⌋ ⌊ m T ⌋ μ ( T d ) = ∏ T = 1 n ( ∏ d ∣ T f [ d ] μ ( T d ) ) ⌊ n T ⌋ ⌊ m T ⌋ \begin {aligned}ans & = \prod _{T = 1} ^n \prod _{d \mid T} f[d] ^{\lfloor \frac n T \rfloor \lfloor \frac m T \rfloor \mu (\frac T d)} \\ &= \prod _{T = 1} ^n (\prod _{d \mid T} f[d] ^{ \mu (\frac T d)}) ^{\lfloor \frac n T \rfloor \lfloor \frac m T \rfloor} \end {aligned} ans=T=1∏nd∣T∏f[d]⌊Tn⌋⌊Tm⌋μ(dT)=T=1∏n(d∣T∏f[d]μ(dT))⌊Tn⌋⌊Tm⌋
整体数论分块,对 ∏ d ∣ T f [ d ] μ ( T d ) \prod _{d \mid T} f[d] ^{ \mu (\frac T d)} ∏d∣Tf[d]μ(dT)预处理:每个数计算它对它的倍数的贡献。
预处理复杂度: ∑ i = 1 n n i ≈ n l o g n \sum _{i=1} ^n \frac n i \approx nlogn ∑i=1nin≈nlogn
同时预处理斐波那契数列的逆元;求 ⌊ n T ⌋ ⌊ m T ⌋ \lfloor \frac n T \rfloor \lfloor \frac m T \rfloor ⌊Tn⌋⌊Tm⌋次方时膜 1 0 9 + 6 10^9+6 109+6
#include <bits/stdc++.h>
using namespace std;
typedef long long ll ;
const int maxn = 1e6 + 10, mod = 1e9 + 7 ;
int mu[maxn], prime[maxn], tot ;
ll f[maxn], g[maxn], F[maxn] ;
bool vis[maxn] ;
ll power (ll x, int y) {
ll res = 1 ;
while (y) {
if (y & 1) res = res * x % mod ;
x = x * x % mod; y >>= 1 ;
}
return res ;
}
void init () {
mu[1] = 1; f[1] = g[1] = F[0] = F[1] = 1 ;
for (int i = 2; i < maxn; i ++) {
f[i] = (f[i - 1] + f[i - 2]) % mod ;
g[i] = power (f[i], mod - 2); F[i] = 1 ;
if (!vis[i]) prime[++ tot] = i, mu[i] = -1 ;
for (int j = 1; j <= tot && i * prime[j] < maxn; j ++) {
vis[i * prime[j]] = 1 ;
if (i % prime[j] == 0) {
mu[i * prime[j]] = 0; break ;
}
mu[i * prime[j]] = -mu[i] ;
}
}
for (int i = 1; i < maxn; i ++) {
if (!mu[i]) continue ;
for (int j = i; j < maxn; j += i)
F[j] = F[j] * (mu[i] == 1 ? f[j / i] : g[j / i]) % mod ;
}
for (int i = 2; i < maxn; i ++) F[i] = F[i] * F[i - 1] % mod ;
}
int main() {
init () ;
int T ;
cin >> T ;
while (T --) {
int n, m ;
scanf("%d%d", &n, &m) ;
if (n > m) swap (n, m) ;
ll ans = 1 ;
for (int i = 1, nxt = 0; i <= n; i = nxt + 1) {
nxt = min (n / (n / i), m / (m / i)) ;
ll t = F[nxt] * power (F[i - 1], mod - 2) % mod ;
ans = ans * power (t, 1ll * (n / i) * (m / i) % (mod - 1)) % mod ;
}
printf("%lld\n", ans) ;
}
return 0 ;
}