BZOJ_2820_YY的GCD_莫比乌斯反演
题意&分析:
$sumlimits_pis[p]sumlimits_{i=1}^{n}sumlimits_{j=1}^{m}[gcd(i,j)=p]$
$=sumlimits_pis[p]sumlimits_{i=1}^{lfloor frac{n}{p}
floor}sumlimits_{j=1}^{lfloor frac{m}{p}
floor}[gcd(i,j)=1]$
$=sumlimits_pis[p]sumlimits_{i=1}^{lfloor frac{n}{p}
floor}sumlimits_{j=1}^{lfloor frac{m}{p}
floor}[gcd(i,j)=1]$
$=sumlimits_pis[p]sumlimits_{i=1}^{lfloor frac{n}{p}
floor}sumlimits_{j=1}^{lfloor frac{m}{p}
floor}sumlimits_{d|gcd(i,j)}mu(d)$
$=sumlimits_pis[p]sumlimits_{d=1}^{lfloor frac{n}{p}
floor}mu(d)sumlimits_{i=1}^{lfloor frac{n}{dp}
floor}sumlimits_{j=1}^{lfloor frac{m}{dp}
floor}$
$=sumlimits_{Q=1}^{n}lfloor frac{n}{Q}
floorlfloorfrac{m}{Q}
floorsumlimits_{p|Q}is[p]mu(lfloorfrac{Q}{p}
floor)$
$f(n)=sumlimits_{p|n}is[p]mu(lfloorfrac{n}{p}
floor)$
首先$f[i]$非积性,但可以通过μ处理,所以我们考虑线筛
1.当$i$为质数时$f[i]=1$;
2.当$i$%$p==0$时
$f(i*p)=sumlimits_{d|i}is[d]mu(i*p/d)$
当$d!=p$时$i*p/d$有两个以上的$p$,贡献为$0$,因此此时$f(i*p)=mu(i)$
3.当$i$%$p!=0$时$i$与$p$互质
$f(i*p)=sumlimits_{d|i}is[d]mu(i*p/d)+sumlimits_{d|p}is[d]mu(i*p/d)$
$=f(i)*mu(p)+f(p)*mu(i)$
$=mu(i)-f(i)$
再记录下f[i]的前缀和,分块计算
代码:
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define LL long long
int prime[4000010],vis[10000100],miu[10000100],f[10000100],sum[10000100],cnt;
int T,n,m;
inline void init()
{
miu[1]=1;
for(int i=2;i<=10000000;i++)
{
if(!vis[i])
{
miu[i]=-1;
f[i]=1;
prime[++cnt]=i;
}
for(int j=1;j<=cnt&&i*prime[j]<=10000000;j++)
{
vis[i*prime[j]]=1;
if(i%prime[j]==0)
{
miu[i*prime[j]]=0;
f[i*prime[j]]=miu[i];
break;
}
miu[i*prime[j]]=-miu[i];
f[i*prime[j]]=miu[i]-f[i];
}
sum[i]=sum[i-1]+f[i];
}
}
int main()
{
init();
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
if(n>m)swap(n,m);
int lst;
LL ans=0;
for(int i=1;i<=n;i=lst+1)
{
lst=min(n/(n/i),m/(m/i));
ans+=1ll*(sum[lst]-sum[i-1])*(n/i)*(m/i);
}
printf("%lld
",ans);
}
}