【洛谷 P2257】 YY的GCD(莫比乌斯反演)
第一道莫比乌斯反演的题
答案是
\[\sum_{T=1}^{n}\lfloor\frac{n}{T}\rfloor\lfloor\frac{m}{T}\rfloor\sum_{k|T,k\in prime}\mu(\frac{T}{k})
\]
具体推导过程以后再补吧。
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int MAXN = 10000010;
int T, n, m, cnt;
long long ans;
int prime[MAXN], mu[MAXN], g[MAXN], sum[MAXN], v[MAXN];
int main(){
mu[1] = 1;
for(int i = 2; i <= 10000000; ++i){
if(!v[i]){
mu[i] = -1;
prime[++cnt] = i;
}
for(int j = 1; j <= cnt; ++j){
if(i * prime[j] > 10000000) break;
v[prime[j] * i] = 1;
if(i % prime[j] == 0) break;
else mu[prime[j] * i] = -mu[i];
}
}
for(int i = 1; i <= cnt; ++i)
for(int j = 1; prime[i] * j <= 10000000; ++j)
g[j * prime[i]] += mu[j];
for(int i = 1; i <= 10000000; ++i)
sum[i] = sum[i-1] + g[i];
scanf("%d", &T);
while(T--){
scanf("%d%d", &n, &m);
ans = 0;
if(n > m) swap(n, m);
for(int l = 1, r = 0; l <= n; l = r + 1){
r = min(n / (n/l), m / (m/l));
ans += (ll)(sum[r] - sum[l-1]) * (n/l) * (m/l);
}
printf("%lld\n", ans);
}
return 0;
}