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;
}
Code

 

posted @ 2020-06-03 08:24  verjun  阅读(234)  评论(0编辑  收藏  举报