【LG2257】YY的GCD

【LG2257】YY的GCD

题面

洛谷

题解

题目大意:

给定\(n,m\)\(\sum_{i=1}^{n}\sum_{j=1}^{m}[gcd(i,j)为质数]\)

我们设\(f(x)=[x为质数]\),需要找到一个\(g\)使得\(f=1*g\),那么\(g=\mu*f\)

\[g(x)=\sum_{d|x}\mu(\frac{x}{d})*f(d)=\sum_{p|x}\mu(\frac{x}{p}) \]

这样的话,我们要求的就是

\[\sum_{i=1}^{n}\sum_{j=1}^{m}\sum_{d|i,d|j}g(d)\\ =\sum_{d=1}^{min(n,m)}g(d)\sum_{i=1}^{n}\sum_{j=1}^{m}[d|i][d|j]\\ =\sum_{d=1}^{min(n,m)}g(d)\lfloor\frac{n}{d}\rfloor\lfloor\frac{m}{d}\rfloor \]

可以用数论分块求出

代码

#include <iostream> 
#include <cstdio> 
#include <cstdlib> 
#include <cstring> 
#include <cmath> 
#include <algorithm> 
using namespace std; 
inline int gi() { 
	register int data = 0, w = 1; 
	register char ch = 0; 
	while (!isdigit(ch) && ch != '-') ch = getchar(); 
	if (ch == '-') w = -1, ch = getchar(); 
	while (isdigit(ch)) data = 10 * data + ch - '0', ch = getchar(); 
	return w * data; 
}
typedef long long ll; 
const int MAX_N = 1e7 + 5; 
const int MAX = 1e7; 
bool is_prime[MAX_N]; 
int prime[MAX_N], num, mu[MAX_N], s[MAX_N], f[MAX_N]; 
void sieve() {
	for (int i = 1; i <= MAX; i++) is_prime[i] = 1; 
	is_prime[1] = 0, mu[1] = 1;
	for (int i = 2; i <= MAX; i++) { 
		if (is_prime[i]) prime[++num] = i, mu[i] = -1; 
		for (int j = 1; j <= num && i * prime[j] <= MAX; j++) {
			is_prime[i * prime[j]] = 0; 
			if (i % prime[j] == 0) break; 
			mu[i * prime[j]] = -mu[i]; 
		} 
	} 
	for (int i = 1; i <= num; i++)
		for (int j = 1; prime[i] * j <= MAX; j++) 
			f[j * prime[i]] += mu[j];
	for (int i = 1; i <= MAX; i++) s[i] = s[i - 1] + f[i]; 
}
ll solve(int a, int b) {
	ll ans = 0;
	if (a > b) swap(a, b);
	for (int l = 1, r = 0; l <= a; l = r + 1) {
		r = min(a / (a / l), b / (b / l));
		ans += 1ll * (s[r] - s[l - 1]) * (a / l) * (b / l); 
	}
	return ans; 
} 
int main () { 
#ifndef ONLINE_JUDGE 
	freopen("cpp.in", "r", stdin); 
#endif
	sieve();
	int T = gi(), N, M; 
	while (T--) {
		N = gi(), M = gi();
		printf("%lld\n", solve(N, M)); 
	} 
	return 0; 
} 
posted @ 2018-12-26 10:23  heyujun  阅读(205)  评论(0编辑  收藏  举报