luoguP5221 Product
题意
求$$\prod_{i=1}^n\prod_{j=1}^n\frac{lcm(i,j)}{\gcd(i,j)}$$
$n\le10^6$
Sol
先把$lcm$化成$\gcd$
$$\prod_{i=1}^n\prod_{j=1}^n\frac{lcm(i,j)}{\gcd(i,j)}$$
$$=\prod_{i=1}^n\prod_{j=1}^n\frac{ij}{\gcd^2(i,j)}$$
将$i,j$与$\frac 1{gcd^2(i,j)}$分开考虑
$$=(\prod_{i=1}^ni\prod_{j=1}^nj)\cdot(\prod_{i=1}^n\prod_{j=1}^n\gcd(i,j))^{-2}$$
$$=(n!)^{2n}\cdot(\prod_{d=1}^nd\prod_{i=1}^n\prod_{j=1}^n[\gcd(i,j)=d])^{-2}$$
将$\prod$转化为指数上的$\sum$
$$=(n!)^{2n}\cdot(\prod_{d=1}^nd^{\sum_{i=1}^n\sum_{j=1}^n[\gcd(i,j)=d]})$$
观察指数
$$\sum_{i=1}^n\sum_{j=1}^n[\gcd(i,j)=d]$$
$$=\sum_{i=1}^{\lfloor \frac nd\rfloor}\sum_{j=1}^{\lfloor \frac nd\rfloor}[\gcd(i,j)=1]$$
$$=2*\varphi(\lfloor \frac nd\rfloor)-1$$
线性筛筛出$\varphi$即可,需要用欧拉定理来对指数取模。
#include <bits/stdc++.h>
using namespace std;
#define Mod 104857601
int phi[1000005], prime[80005], tot = 0;
bool vis[1000005];
long long qpow(long long a, long long b)
{
long long res = 1;
while (b)
{
if (b & 1)
res = res * a % Mod;
a = a * a % Mod;
b >>= 1;
}
return res;
}
void prework(int n)
{
phi[1] = 1;
for (int i = 2; i <= n; i++)
{
if (!vis[i])
{
prime[++tot] = i;
phi[i] = i - 1;
}
for (int j = 1; j <= tot && i * prime[j] <= n; j++)
{
vis[i * prime[j]] = 1;
if (i % prime[j] == 0)
{
phi[i * prime[j]] = phi[i] * prime[j];
break;
}
phi[i * prime[j]] = phi[i] * (prime[j] - 1);
}
}
for (int i = 2; i <= n; i++)
{
phi[i] = (phi[i - 1] + phi[i]) % (Mod - 1);
}
}
int main()
{
int n;
cin >> n;
prework(n);
long long ans1 = 1, ans2 = 1;
for (int i = 1; i <= n; i++)
{
ans1 = ans1 * i % Mod;
}
ans1 = qpow(ans1, 2 * n);
for (int i = 1; i <= n; i++)
{
ans2 *= qpow(i, (2 * phi[n / i] - 1) % (Mod - 1));
ans2 %= Mod;
}
ans2 = qpow(ans2 * ans2 % Mod, Mod - 2);
cout << ans1 * ans2 % Mod << endl;
}