# BZOJ2301 容斥原理,莫比乌斯反演

## Description

solve(b,d)-solve(a-1,d)-solve(b,c-1)+solve(a-1,c-1)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
int miu[50010];
int sum[50010];
int prime[50010];
bool notprm[50010];
const int MAXN=50001;
int cnt;
long long ans;
int a,b,c,d,k;
void init()
{
miu[1]=1;
for(int i=2;i<=MAXN;++i)
{
if(!notprm[i])
{
prime[cnt++]=i;
miu[i]=-1;
}
for(int j=0;j<cnt&&i*prime[j]<=MAXN;++j)
{
notprm[i*prime[j]] = 1;
if(i%prime[j])miu[i*prime[j]]=-miu[i];
else
{
miu[i*prime[j]]=0;
break;
}
}
}
for(int i=1;i<=MAXN;++i)
sum[i]=sum[i-1]+miu[i];
}
long long solve(int x,int y)
{
long long res=0;
if(x>y)swap(x,y);
for(long long i=1,l=0;i<=x;i=l+1)
{
l=min(x/(x/i),y/(y/i));
res+=(sum[l]-sum[i-1])*(x/i)*(y/i);
}
return res;
}
int main()
{
init();
int T;
cin>>T;
while(T--)
{
cin>>a>>b>>c>>d>>k;
if(a>b||c>d)
{
cout<<0<<endl;
continue;
}
ans=solve(b/k,d/k);
ans-=solve((a-1)/k,d/k);
ans-=solve(b/k,(c-1)/k);
ans+=solve((a-1)/k,(c-1)/k);
cout<<ans<<endl;
}
}

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