题解 P2257 【YY的GCD】
题目链接:Luogu 2257
求解(多组数据)
数据范围:
Solution
以下所有过程中默认
首先我们很自然想到枚举质数
根据套路提出
替换
枚举
由于
这个式子直接求解的复杂度为
考虑优化:令
枚举
设
如果我们能求出
-
x\in\texttt{prime}$:显然有 $f(x)=\mu(1)=1 -
- 当 $i$ 没有多个相同质因子时,那么当且仅当枚举的 $p=y$ 时,$\mu(\frac{x}{p})=\mu(i)$ 不为 $0$,故 $f(x)=\mu(i) - 当
i 也有多个相同质因子时,那么对于任何枚举的p ,都有\mu(\frac{x}{p}) 的值都为0 ,此时仍然有\mu(\frac{x}{p})=\mu(i) ,故f(x)=\mu(i)
- 当
-
因为有 $f(i)=\sum\limits_{p\in\texttt{prime},p\mid i}\mu(\frac{i}{p})$,$f(x)=\sum\limits_{p\in\texttt{prime},p\mid x}\mu(\frac{i\times y}{p}) 根据
\mu 的线性筛过程,有\mu(\frac{i\times y}{p})=-\mu(\frac{i}{p}) ,因此f(i) 中的每一项能都在f(x) 中找到对应的一项。而x 比i 多且仅多了一个质因子y ,因此f(x) 比f(i) 多了一项\mu(\frac{i\times y}{y})=\mu(i) ,故f(x)=-f(i)+\mu(i)
综上所述,我们可以得到
通过求
时间复杂度:
Code
#include <cstdio>
#include <algorithm>
const int N=1e7+5,lnN=15;
int n,m,tot,p[N/lnN],mu[N],f[N];
bool flg[N];
void init() {
mu[1]=flg[1]=1;
for(int i=2;i<N;++i) {
if(!flg[i]) p[++tot]=i,mu[i]=-1,f[i]=1;
for(int j=1;j<=tot&&i*p[j]<N;++j) {
int x=i*p[j];
flg[x]=1;
if(i%p[j]==0) {
f[x]=mu[i];
mu[x]=0;
break;
} else {
f[x]=-f[i]+mu[i];
mu[x]=-mu[i];
}
}
f[i]+=f[i-1];
}
}
int main() {
init();
int T;
for(scanf("%d",&T);T--;) {
scanf("%d%d",&n,&m);
long long ans=0;
if(n>m) n^=m^=n^=m;
for(int i=1,j;i<=n;i=j+1) {
j=std::min(n/(n/i),m/(m/i));
ans+=1LL*(f[j]-f[i-1])*(n/i)*(m/i);
}
printf("%lld\n",ans);
}
return 0;
}