# bzoj_2301_HAOI2011_Problem b 莫比乌斯反演

$$F(n)=\sum_{d|n}f(d)$$

$$f(i)=\sum_{i|d}\mu(\frac{d}{i})\lfloor\frac{n}{d}\rfloor\lfloor\frac{m}{d}\rfloor$$

$$f(i)=\sum_{d=1}^{min(n,m)}\lfloor\frac{n}{d}\rfloor\lfloor\frac{m}{d}\rfloor\sum_{i|d}\mu(\frac{d}{i})$$

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <algorithm>
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
const int N=100006;

int prime[N],cnt,mu[N];
bool he[N];

void chu()
{
mu[1]=1;
for(int i=2;i<N;++i)
{
if(!he[i])
{
prime[++cnt]=i;
mu[i]=-1;
}
for(int j=1;j<=cnt&&prime[j]*i<N;++j)
{
he[i*prime[j]]=1;
if(i%prime[j]==0)
{
mu[i*prime[j]]=0;
break;
}
mu[i*prime[j]]=-mu[i];
}
}

for(int i=1;i<N;++i)
mu[i]+=mu[i-1];
}

int Q;
int K;

int get(int n,int m)
{
n/=K;m/=K;
if(n>m)
swap(n,m);
int nx,ans=0;
for(int i=1;i<=n;)
{
nx=min( n/(n/i),m/(m/i) );
//printf("nx=%d\n",nx);
ans+=(mu[nx]-mu[i-1])*(m/i)*(n/i);
i=nx+1;
}
//printf("n=%d m=%d ans=%d\n",n,m,ans);
return ans;
}

int main(){

freopen("in.in","r",stdin);

chu();

scanf("%d",&Q);
int l0,r0,l1,r1;
for(int i=1;i<=Q;++i)
{
//printf("i=%d\n",i);
scanf("%d%d%d%d%d",&l0,&r0,&l1,&r1,&K);
printf("%d\n",get(r0,r1)-get(l0-1,r1)-get(l1-1,r0)+get(l0-1,l1-1));
}

}
bzoj 2301

posted @ 2017-10-07 11:06  A_LEAF  阅读(...)  评论(...编辑  收藏