题意:
给出n,mn,mn,m,计算有多少i∈[1,n],j∈[1,m]i\in[1,n],j\in[1,m]i∈[1,n],j∈[1,m],使得gcd(i,j)gcd(i,j)gcd(i,j)是一个素数
Solution:
不妨转化为枚举这个素数,找有多少对满足条件
∑p∈prime∑i=1n∑j=1m[gcd(i,j)=p]
\sum_{p\in prime}\sum_{i=1}^{n}\sum_{j=1}^{m}[gcd(i,j)=p]
p∈prime∑i=1∑nj=1∑m[gcd(i,j)=p]
凑出莫比乌斯反演的形式,得到
∑p∈prime∑i=1⌊np⌋∑j=1⌊mp⌋∑d∣gcd(i,j)μ(d)
\sum_{p\in prime}\sum_{i=1}^{\lfloor\frac{n}{p}\rfloor}\sum_{j=1}^{\lfloor\frac{m}{p}\rfloor}\sum_{d|gcd(i,j)}\mu(d)
p∈prime∑i=1∑⌊pn⌋j=1∑⌊pm⌋d∣gcd(i,j)∑μ(d)
优先枚举因子,并且设n≤mn\leq mn≤m
∑p∈prime∑d=1⌊np⌋μ(d)⌊npd⌋⌊mpd⌋
\sum_{p\in prime}\sum_{d=1}^{\lfloor\frac{n}{p}\rfloor}\mu(d)\lfloor\frac{n}{pd}\rfloor\lfloor\frac{m}{pd}\rfloor
p∈prime∑d=1∑⌊pn⌋μ(d)⌊pdn⌋⌊pdm⌋
优先枚举乘积,然后就可以将一部分转化为枚举因子,这里枚举T=pdT=pdT=pd
∑T=1n⌊nT⌋⌊mT⌋∑p∈prime,p∣Tμ(Tp)
\sum_{T=1}^{n}\lfloor\frac{n}{T}\rfloor\lfloor\frac{m}{T}\rfloor\sum_{p\in prime,p|T} \mu(\frac{T}{p})
T=1∑n⌊Tn⌋⌊Tm⌋p∈prime,p∣T∑μ(pT)
前面的部分可以数论分块解决,现在只需要快速求得
f(T)=∑p∈prime,p∣Tμ(Tp)
f(T)=\sum_{p\in prime,p|T} \mu(\frac{T}{p})
f(T)=p∈prime,p∣T∑μ(pT)
可以线性筛筛出这个函数,线性筛关键在于添加一个质因子会带来什么后果,这里我们假设给TTT加上一个质因子ppp
有关莫比乌斯函数,不妨先假设TTT的唯一分解为:
T=p1a1p2a2...pnan
T=p_{1}^{a_{1}}p_{2}^{a_{2}}...p_{n}^{a_{n}}
T=p1a1p2a2...pnan
-
如果TTT包含了ppp,那么TpTpTp的唯一分解中ppp的幂≥2\geq2≥2,而当p′≠pp'\neq pp′=p时Tp′\frac{T}{p'}p′T必然包括平方因子p2p^2p2,此时所有的莫比乌斯函数值为000,只有当p′=pp'=pp′=p时,Tp′\frac{T}{p'}p′T才有可能不出现平方因子,于是此时
f(Tp)=μ(T) f(Tp)=\mu(T) f(Tp)=μ(T) -
如果TTT不包含ppp,那么此时TpTpTp的唯一分解为
Tp=p1a1p2a2...pnanp Tp=p_{1}^{a_{1}}p_{2}^{a_{2}}...p_{n}^{a_{n}}p Tp=p1a1p2a2...pnanp枚举出所有的Tp′\frac{T}{p'}p′T,有
p2a2p3a3...pnanpp1a1p3a3...pnanpp1a1p2a2...pnanp...p1a1p2a2...pnan p_{2}^{a_{2}}p_{3}^{a_{3}}...p_{n}^{a_{n}}p\\ p_{1}^{a_{1}}p_{3}^{a_{3}}...p_{n}^{a_{n}}p\\ p_{1}^{a_{1}}p_{2}^{a_{2}}...p_{n}^{a_{n}}p\\ ...\\ p_{1}^{a_{1}}p_{2}^{a_{2}}...p_{n}^{a_{n}} p2a2p3a3...pnanpp1a1p3a3...pnanpp1a1p2a2...pnanp...p1a1p2a2...pnan
除了最后一项都带有ppp,而莫比乌斯函数是个积性函数,所以要求除了最后一项的莫比乌斯函数值,可以求得前面的部分,再乘μ(p)\mu(p)μ(p),比如说第一项
μ(p2a2p3a3...pnanp)=μ(p2a2p3a3...pnan)μ(p) \mu(p_{2}^{a_{2}}p_{3}^{a_{3}}...p_{n}^{a_{n}}p)=\mu(p_{2}^{a_{2}}p_{3}^{a_{3}}...p_{n}^{a_{n}})\mu(p) μ(p2a2p3a3...pnanp)=μ(p2a2p3a3...pnan)μ(p)
此时我们将除最后一项的其他项都写成这样的形式,可以提出一个μ(p)\mu(p)μ(p),此时这些的求和就为
μ(p)[μ(p2a2p3a3...pnan)+μ(p1a1p3a3...pnan)+μ(p1a1p2a2...pnan)] \mu(p)[\mu(p_{2}^{a_{2}}p_{3}^{a_{3}}...p_{n}^{a_{n}})+\mu(p_{1}^{a_{1}}p_{3}^{a_{3}}...p_{n}^{a_{n}})+\mu(p_{1}^{a_{1}}p_{2}^{a_{2}}...p_{n}^{a_{n}})] μ(p)[μ(p2a2p3a3...pnan)+μ(p1a1p3a3...pnan)+μ(p1a1p2a2...pnan)]
中括号内的部分恰好就是f(T)f(T)f(T),于是这部分值就为μ(p)f(T)\mu(p)f(T)μ(p)f(T)最后一项即TTT本身的莫比乌斯函数值,于是此时有
f(Tp)=μ(p)f(T)+μ(T) f(Tp)=\mu(p)f(T)+\mu(T) f(Tp)=μ(p)f(T)+μ(T)
最后在数论分块的时候需要区间求和f(T)f(T)f(T),给f(T)f(T)f(T)做一个前缀和即可O(1)O(1)O(1)求出
// #include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<vector>
#include<bitset>
#include<map>
using namespace std;
using ll=long long;
const int N=1e7+5;
bool nt[N];
int prime[N],cnt,mu[N],f[N];
void make_prime()
{
mu[1]=1;
for(int i=2;i<=10000000;i++)
{
if(!nt[i]) prime[++cnt]=i,mu[i]=-1,f[i]=1;
for(int j=1;j<=cnt&&i*prime[j]<=10000000;j++)
{
nt[i*prime[j]]=true;
if(i%prime[j]==0)
{
mu[i*prime[j]]=0;
f[i*prime[j]]=mu[i];
break;
}
else
{
mu[i*prime[j]]=mu[i]*mu[prime[j]];
f[i*prime[j]]=mu[i]+f[i]*mu[prime[j]];
}
}
}
for(int i=1;i<=10000000;i++) f[i]+=f[i-1];
}
int main()
{
make_prime();
int t; cin>>t;
while(t--)
{
int n,m; ll ans=0; scanf("%d%d",&n,&m);
if(n>m) swap(n,m);
for(int l=1,r;l<=n;l=r+1)
{
r=min(n/(n/l),m/(m/l));
ans+=1ll*(n/l)*(m/l)*(f[r]-f[l-1]);
}
printf("%lld\n",ans);
}
return 0;
}
这篇博客探讨了一道数学与编程结合的问题,涉及最大公约数(GCD)和素数的计算。通过莫比乌斯反演,作者展示了如何在O(n log n)的时间复杂度内,计算对于所有1到n和1到m的整数对(i, j),GCD为素数的情况数量。文章详细解释了线性筛法在解决该问题中的应用,包括如何处理质因子的添加和移除,以及如何进行数论分块以优化计算。
1147

被折叠的 条评论
为什么被折叠?



