P2257 YY的GCD

题目链接

YY‘ GCD

\[f(x) = \sum\limits_{i=1}^{n} \sum\limits_{j=1}^m[\gcd(i, j) = 1] \]

\[F(x) = \sum\limits_{x|d}f(d)=\lfloor\frac{n}{x}\rfloor\lfloor\frac{m}{x}\rfloor \]

\[\sum\limits_{p\in P}f(p) \]

\[\begin{align*} \sum\limits_{p\in P}f(p) & = \sum\limits_{p\in P}\sum\limits_{i=1}^{\lfloor\frac{n}{p}\rfloor} \sum\limits_{j=1}^{\lfloor\frac{m}{p}\rfloor}[\gcd(i, j) = 1] \\ & = \sum\limits_{p\in P} \sum\limits_{p|d} \mu(\frac{d}{p})F(d) \\ & = \sum\limits_{p\in P} \sum\limits_{d=1} \mu(d)F(dp) \\ \text{令 T 为 $dp$} \\ & = \sum\limits_{T=1}^{\min(n, m)}F(T)\sum\limits_{p\in P,p|d}^{d}\mu(\frac{T}{p}) \\ & = \sum\limits_{T=1}^{\min(n, m)}\lfloor\frac{n}{T}\rfloor\lfloor\frac{m}{T}\rfloor\sum\limits_{p\in P,p|d}^{d}\mu(\frac{T}{p}) \end{align*} \]

使用整除分块

使用欧拉筛处理 \(\mu\)

由于外部循环使用整除分块,使用前缀和预处理 \(\sum\limits_{p\in P,p|d}^{d}\mu(\frac{T}{p})\)

代码如下:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const int N = 1e7+10;

int n, m, notPrime[N], mu[N], f[N];
ll sum[N];
vector<int>prime;

void euler(int n){
	mu[1] = 1;
	for(int i=2;i<=n;i++){ 
		if(!notPrime[i]){
			mu[i] = -1;
			prime.push_back(i);
		}
		for(auto p : prime){		
			if(p*i>n) break;
			notPrime[p*i] = 1;
			if(i%p==0){
				mu[i*p] = 0;
				break;
			}
			mu[i*p]=-mu[i]; 
		}
	}
	for(auto p : prime)
        for(int i=1;i*p<=n;i++)f[i*p]+=mu[i];
    for(int i=1;i<=n;i++)sum[i]=sum[i-1]+1ll*f[i];
}

void solve(){
	ll ans=0;cin>>n>>m;
	for(int l=1,r=0;l<=min(n, m);l=r+1){
		r = min(n/(n/l), m/(m/l));
		ans += 1ll*(sum[r]-sum[l-1])*(n/l)*(m/l);
	} 
	cout<<ans<<'\n';
}

int main(){
	euler(1e7);
	int T;cin>>T;
	while(T--) solve();
}
posted @ 2025-07-11 23:39  fyv233  阅读(20)  评论(0)    收藏  举报