# 【BZOJ 2301】Problem B 莫比乌斯反演

## 题意

n$n$个询问。
bi=adj=c[gcd(i,j)=k]$\sum_{i=a}^b\sum_{j=c}^d [\gcd(i,j)=k]$
1n50000ab500001cd500001k50000$1\leq n\leq 50000，≤a≤b≤50000，1≤c≤d≤50000，1≤k≤50000$

## 分析

F(n)=n|df(d)f(n)=n|dμ(dn)F(d)$F(n)=\sum_{n|d}f(d)\Rightarrow f(n)=\sum_{n|d}\mu({d\over n})F(d)$

ni=1mj=1[gcd(i,j)=k]$\sum_{i=1}^n \sum_{j=1}^m [\gcd(i,j)=k]$

F(k)=ni=1mj=1[k|gcd(i,j)]=nkmk$F(k)=\sum_{i=1}^n \sum_{j=1}^m [k|\gcd(i,j)]=\lfloor {n\over k}\rfloor \lfloor {m\over k}\rfloor$

f(k)=k|dμ(dk)F(d)=k|dμ(dk)ndmd$\therefore f(k)=\sum_{k|d}\mu({d\over k})F(d)=\sum_{k|d}\mu({d\over k})\lfloor {n\over d}\rfloor \lfloor {m\over d}\rfloor$

f(n)=ni=1μ(i)nkimki$\therefore f(n)=\sum_{i=1}^n\mu(i)\lfloor {n\over {ki}}\rfloor \lfloor {m\over {ki}}\rfloor$

②当d>n$d>\sqrt n$时，nd<n${n\over d}<\sqrt n$，又因为是整数，所以最多只有n$\sqrt n$个取值。

## 代码

#include <cstdio>
#include <cstring>
#include <cctype>
#include <algorithm>
using namespace std;

const int N=50001;

int vis[N],mu[N],pri[N],tot,suf[N];
int cas;
int a,b,c,d,k;
int s1,s2,s3,s4,ans;

{
int x=0; char c=getchar();
for (;!isdigit(c);c=getchar());
for (;isdigit(c);c=getchar()) x=x*10+c-'0';
return x;
}

int query(int n,int m)
{
int a=n/k,b=m/k; int l,r; int calc=0;
if (a>b) swap(a,b);
for (l=1;l<=a;l=r+1)
{
r=min(a/(a/l),b/(b/l));
calc=calc+(a/l)*(b/l)*(suf[r]-suf[l-1]);
}
return calc;
}

int main(void)
{
//  freopen("a.in","r",stdin);
//  freopen("a.out","w",stdout);

vis[1]=mu[1]=1;
for (int i=2;i<N;i++)
{
if (!vis[i])
{
mu[i]=-1;
pri[++tot]=i;
}
for (int j=1;j<=tot;j++)
{
if (i*pri[j]>=N) break;
vis[i*pri[j]]=1;
if (i%pri[j]!=0)
mu[i*pri[j]]=-mu[i];
else
{
mu[i*pri[j]]=0;
break;
}
}
}
for (int i=1;i<N;i++)
suf[i]=suf[i-1]+mu[i];

for (int cc=1;cc<=cas;cc++)
{
s1=query(b,d);
s2=query(a-1,d);
s3=query(b,c-1);
s4=query(a-1,c-1);
ans=s1+s4-s2-s3;
printf("%d\n",ans);
}

return 0;
}

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客