# BZOJ 2301 Problem b（莫比乌斯反演）

Description

Input

Output

Sample Input
2
2 5 1 5 1
1 5 1 5 2
Sample Output
14
3
Solution

Code

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
#define maxn 55555
typedef long long ll;
bool check[maxn];
int prime[maxn],mu[maxn],sum[maxn];
void Moblus(int n)
{
memset(check,0,sizeof(check));
mu[1]=sum[1]=1;
int tot=0;
for(int i=2;i<=n;i++)
{
if(!check[i])
{
prime[tot++]=i;
mu[i]=-1;
}
for(int j=0;j<tot;j++)
{
if(i*prime[j]>n)break;
check[i*prime[j]]=1;
if(i%prime[j]==0)
{
mu[i*prime[j]]=0;
break;
}
else mu[i*prime[j]]=-mu[i];
}
sum[i]=sum[i-1]+mu[i];
}
}
ll solve(int n,int m,int k)
{
n=n/k,m=m/k;
if(n>m)swap(n,m);
ll ans=0;
for(int i=1,next=0;i<=n&&i<=m;i=next+1)
{
next=min(n/(n/i),m/(m/i));
ans+=1ll*(n/i)*(m/i)*(sum[next]-sum[i-1]);
}
return ans;
}
int T,a,b,c,d,k;
int main()
{
Moblus(maxn-10);
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d%d%d",&a,&b,&c,&d,&k);
a--,c--;
ll ans=solve(b,d,k)-solve(a,d,k)-solve(b,c,k)+solve(a,c,k);
printf("%lld\n",ans);
}
return 0;
}

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