莫比乌斯反演复健:Problem b(由于太颓废了也是6.30-7.6的周报)
莫比乌斯反演复健:Problem b(由于太颓废了也是6.30-7.6的周报)
先来一个莫比乌斯反演常见的模板
\[\begin{aligned}
&\sum_i^n\sum_j^m[\gcd(i,j)=1]\\
\iff&\sum_i^n\sum_j^m\sum_{d|\gcd(i,j)}\mu(d)\\
\iff&\sum_{d=1}^n\mu(d)\sum_i^n\sum_j^m[d|\gcd(i,j)]\\
\iff&\sum_{d=1}^n\mu(d)\lfloor\frac{n}{d}\rfloor\lfloor\frac{m}{d}\rfloor\\
\end{aligned}
\]
对于该问题,经过简单的充斥,等同于去求
\[\begin{aligned}
&\sum_i^n\sum_j^m[\gcd(i,j)=k]\\
\iff&\sum_i^{\lfloor\frac{n}{k}\rfloor}\sum_j^{\lfloor\frac{m}{k}\rfloor}[\gcd(i,j)=1]\\
\iff&\sum_i^{\lfloor\frac{n}{k}\rfloor}\sum_j^{\lfloor\frac{m}{k}\rfloor}\sum_{d|\gcd(i,j)}\mu(d)\\
\iff&\sum_{d=1}^n\mu(d)\sum_i^{\frac{n}{k}}
\sum_j^{\frac{m}{k}}[d|\gcd(i,j)]\\
\iff&\sum_{d=1}^n\mu(d)\lfloor\frac{n}{kd}
\rfloor\lfloor\frac{m}{kd}\rfloor\\
\end{aligned}
\]
用整数分块和容斥原理处理即可
f(a,b,c,d)=g(b,d)-g(a,c-1)-g(a-1,c)+g(a-1,c-1)
代码如下:
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define MAXN 50005
LL n,p,cnt,sum[MAXN];
int mu[MAXN],prime[MAXN];
bool vis[MAXN];
void oula(LL n)
{
mu[1]=1;
for(int i=2;i<=n;i++)
{
if(!vis[i])
{
prime[++cnt]=i;
mu[i]=-1;
}
for(int j=1;j<=cnt&&i*prime[j]<=n;j++)
{
vis[i*prime[j]]=1;
if(i%prime[j])
{
mu[i*prime[j]]=-mu[i];
}else{
break;
}
}
}
for(int i=1;i<=n;i++)sum[i]=sum[i-1]+mu[i];
}
LL solve(LL n,LL m)
{
if(n>m)swap(n,m);
LL ret=0;
for(LL l=1,r=0;l<=n;l=r+1)
{
r=min(n/(n/l),m/(m/l));
ret+=(sum[r]-sum[l-1])*(n/l)*(m/l);
}
return ret;
}
int main()
{
int T;
scanf("%d",&T);
oula(50000);
while(T --> 0)
{
LL a,b,c,d,k;
cin>>a>>b>>c>>d>>k;
cout<<solve((a-1)/k,(c-1)/k)+solve(b/k,d/k)-solve((a-1)/k,d/k)-solve((c-1)/k,b/k)<<endl;
}
return 0;
}
浙公网安备 33010602011771号