【洛谷 P2257】 YY的GCD(莫比乌斯反演)

第一道莫比乌斯反演的题
答案是

[sum_{T=1}^{n}lfloorfrac{n}{T} floorlfloorfrac{m}{T} floorsum_{k|T,kin 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
", ans);
	}
	return 0;
}
原文地址:https://www.cnblogs.com/Qihoo360/p/15300389.html