bzoj2301: [HAOI2011]Problem b

模板莫比乌斯反演

#include<bits/stdc++.h>
using namespace std;
bool not_prime[50100];
int prime[50100],tot=0,sum[50100],mu[50100],a,b,c,d,k,T;
int getit(int aa,int bb)
{
	if(aa>bb)swap(aa,bb);
	int last,ans=0;
	for(int i=1;i<=aa;i=last+1)
	{
		last=min(aa/(aa/i),bb/(bb/i));
		ans+=(aa/i)*(bb/i)*(sum[last]-sum[i-1]);
	}
	return ans;
}
int main()
{
	scanf("%d",&T);
	mu[1]=1;
	for(int i=2;i<=50000;i++)
	{
		if(!not_prime[i])
		{
			prime[++tot]=i;
			mu[i]=-1;
		}
		for(int j=1;j<=tot&&i*prime[j]<=50000;j++)
		{
			not_prime[prime[j]*i]=true;
			if(i%prime[j]==0)
			{
				mu[i*prime[j]]=0;
				break;
			}
			mu[i*prime[j]]=-1*mu[i];
		}
	}
	for(int i=1;i<=50000;i++)
		sum[i]=sum[i-1]+mu[i];
	while(T--)
	{
		scanf("%d%d%d%d%d",&a,&b,&c,&d,&k);
		a--;c--;
		a/=k;b/=k;c/=k;d/=k;
		printf("%d\n",getit(b,d)+getit(a,c)-getit(a,d)-getit(c,b));
	}
	return 0;
}

  

posted @ 2018-01-23 14:15  mybing  阅读(125)  评论(0编辑  收藏  举报