天守阁的地板 题解

这题还是挺值得一做的。


简要题意:
(1000)

[prod_{i=1}^n prod_{j=1}^n frac{lcm(i,j)^2}{i*j} ]

(i、j) 规模均为 (1e6)


淦。

[prod_{i=1}^n prod_{j=1}^n frac{lcm(i,j)^2}{i*j} ]

[= prod_{i=1}^n prod_{j=1}^n frac{i*j}{gcd(i,j)^2} ]

由于是累乘, 所以拆开来算

[= frac{ prod_{i=1}^n prod_{j=1}^n i*j } { prod_{i=1}^n prod_{j=1}^n gcd(i,j)^2} ]

上面的直接预处理, 重点是下面的。

[prod_{i=1}^n prod_{j=1}^n gcd(i,j)^2 ]

[= prod_{g=1}^n g^{2 * sum_{i=1}^{lfloor frac{n}g floor} sum_{j=1}^{lfloor frac{n}g floor} [gcd(i,j)==1]} ]

(f(n) = sum_{i=1}^{n} sum_{j=1}^{n} [gcd(i,j)==1])

于是

[prod_{g=1}^n g^{2 * sum_{i=1}^{lfloor frac{n}g floor} sum_{j=1}^{lfloor frac{n}g floor} [gcd(i,j)==1]} ]

[= prod_{g=1}^n g^{2 * f(lfloor frac{n}g floor)} ]

可以分块套快速幂算。

(f(n))怎么算?

[f(n) = sum_{i=1}^{n} sum_{j=1}^{n} [gcd(i,j)==1] ]

[= 2*sum_{i=1}^n varphi(i)-1 ]

也可以预处理。

总复杂度就是 (O(n)) 预处理 加上 (O( T sqrt n * 快速幂的log))


Luogu 数据 AC 代码:

#include<bits/stdc++.h>
using namespace std;
#define li long long
const int mod = 19260817; // prime
const int maxn = 1e6 + 15;
li ksm(li a, li b, li p) {
	li res = 1ll;
	for(;b;b>>=1, a=(a*a)%p)
		if(b&1) res = (res*a)%p;
	return res%p;
}

li jc[maxn], phi[maxn];
int pr_cnt, prime[maxn], v[maxn];
void euler(int n) {
	jc[0] = 1ll;
	phi[1] = 1ll;
	for(int i=2; i<=n; ++i) {
		if(!v[i]) {
			v[prime[++pr_cnt] = i] = i;
			phi[i] = i-1ll;
		}
		for(int j=1; j<=pr_cnt; ++j) {
			if(prime[j] > n/i || prime[j] > v[i]) break;
			v[prime[j] * i] = prime[j];
			phi[prime[j] * i] = phi[i] * (i%prime[j] ? prime[j]-1 : prime[j]);
		}
	}
	for(int i=1; i<=n; ++i) {
		jc[i] = 1ll * jc[i-1] * i % mod;
		phi[i] += phi[i-1];
	}
}

li f(int n) {
	return 2ll*phi[n] - 1ll;
}

signed main()
{
	euler(1000000);
	int T,n; cin >> T; while(T--) {
		scanf("%d", &n);
		li ans = ksm(jc[n],2*n,mod);
		li downans = 1ll;
		for(int i=1,j;i<=n;i=j+1) {
			j = min(n, n/(n/i));
			li b = 2 * f(n/i);
			li a = jc[j] * ksm(jc[i-1],mod-2,mod) % mod;
			downans *= ksm(a,b,mod);
			downans = (downans%mod+mod)%mod;
		}
		ans *= ksm(downans,mod-2,mod);
		ans = (ans%mod+mod)%mod;
		cout << ans << '
';
	}
	return 0;
}
原文地址:https://www.cnblogs.com/tztqwq/p/12765467.html