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();
}

浙公网安备 33010602011771号