题目大意:给定两个区间ab与cd问两区间内能有多少组数据组成GCD(x,y)=k;
每行五个整数a,b,c,d,k(1 <= a <= b <= 50000,1 <= c <= d <=50000,1 <= k <= 50000)。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<math.h>
#define ll long long
#define MAX 1000010
bool vis[1000010];
ll prime[1000010],mu[1000010],su[1000010];
using namespace std;
void mobus()
{
memset(vis,false,sizeof(vis));
mu[1]=1;
int s=0;
for(int i=2; i<=1000000; i++)
{
if(!vis[i])
{
prime[s++]=i;
mu[i]=-1;
}
for(int j=0; j<s&&prime[j]*i<=1000010; j++)
{
vis[prime[j]*i ]=true;
if(i%prime[j]==0)
{
mu[i*prime[j]]=0;
break;
}
else
mu[i*prime[j] ]=-mu[i];
}
}
}
ll so(int n,int m)
{
ll ans=0;
if(n>m)
{
n^=m; m^=n;n^=m;
}
for(int i=1,la=0; i<=n; i=la+1)
{
la=min(n/(n/i),m/(m/i));
ans+=(ll )(su[la]-su[i-1])*(n/i)*(m/i);
}
return ans;
}
int main()
{
ll n,m,i,j,a1,b1,c1,d1,k1,a,b,c,d,k;
mobus();
su[0]=0;
for(i=1; i<=60000; i++)
su[i]=su[i-1]+mu[i];
int cla;
scanf("%d",&cla);
for(int gr=1; gr<=cla; gr++)
{
scanf("%lld%lld%lld%lld%lld",&a,&b,&c,&d,&k);
printf("%lld\n",so(b/k,d/k)-so((a-1)/k,d/k)-so(b/k,(c-1)/k)+so((a-1)/k,(c-1)/k));
}
return 0;
}