Luogu5221 Product

题面

题解

首先,这种式子肯定是莫比乌斯反演之类的套路

[egin{aligned} & prod_{i=1}^nprod_{j=1}^n frac{mathrm{lcm}(i,j)}{gcd(i,j)} \ =& prod_{i=1}^nprod_{j=1}^n frac{ij}{gcd^2(i,j)} \ end{aligned} ]

其中

[egin{aligned} &prod_{i=1}^nprod_{j=1}^n gcd(i,j)\ =&prod_{d=1}^n d^{sum_{i=1}^nsum_{j=1}^n[gcd(i,j)=d]} end{aligned} ]

然后暴力反演或者求(varphi)即可


这种方法太( exttt{naive})了,换一种

考虑筛出(f(i) = prod_{j=1}^n gcd(i,j))

(i in mathrm{prime})时,(f(i) = i^{n / i})

否则找到一个质因子(p)

(i = i' imes p^a),那么因为(p)能够加到(prod gcd(i,j))的总贡献是(p^{n / p^a}),所以

[f(i) = f(i') imes p^{n / p^a} ]

然后暴力线性筛就可以了

时间复杂度大约是(mathrm{O}(nlog_2 n))

代码

这里面的(ans)就是(f)

#include<cstdio>
#include<cstring>
#include<cctype>
#include<algorithm>
#define RG register
#define file(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
#define clear(x, y) memset(x, y, sizeof(x))

inline int read()
{
	int data = 0, w = 1; char ch = getchar();
	while(ch != '-' && (!isdigit(ch))) ch = getchar();
	if(ch == '-') w = -1, ch = getchar();
	while(isdigit(ch)) data = data * 10 + (ch ^ 48), ch = getchar();
	return data * w;
}

const int maxn(1000010), Mod(104857601);
int prime[maxn >> 2], ans[maxn], n, mul = 1, s = 1, cnt;
bool not_prime[maxn];

int fastpow(int x, int y)
{
	int ans = 1;
	while(y)
	{
		if(y & 1) ans = 1ll * ans * x % Mod;
		x = 1ll * x * x % Mod, y >>= 1;
	}
	return ans;
}

void init()
{
	ans[1] = 1;
	for(RG int i = 2; i <= n; i++)
	{
		if(!not_prime[i]) ans[prime[++cnt] = i] = fastpow(i, n / i);
		for(RG int j = 1; j <= cnt && 1ll * i * prime[j] <= n; j++)
		{
			int k = i * prime[j], k_1 = k, p = prime[j], pow = 1;
			not_prime[k] = 1;
			while(!(k % p)) k /= p, pow *= p;
			ans[k_1] = ans[i] * fastpow(p, n / pow);
			if(!(i % prime[j])) break;
		}
	}
}

int main()
{
	n = read(); init();
	for(RG int i = 1; i <= n; i++) mul = 1ll * mul * i % Mod;
	mul = fastpow(mul, n << 1);
	for(RG int i = 2; i <= n; i++)
		s = 1ll * s * ans[i] % Mod;
	s = fastpow(s, Mod - 3);
	printf("%lld
", 1ll * mul * s % Mod);
	return 0;
}
原文地址:https://www.cnblogs.com/cj-xxz/p/10386719.html