【洛谷 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;
}
posted @ 2021-09-16 19:55  Qihoo360  阅读(68)  评论(0编辑  收藏  举报
You're powerful!