Please notice that, (x=5, y=7) and (x=7, y=5) are considered to be the same.
Yoiu can assume that a = c = 1 in all test cases.
Each case contains five integers: a, b, c, d, k, 0 < a <= b <= 100,000, 0 < c <= d <= 100,000, 0 <= k <= 100,000, as described above.
2 1 3 1 5 1 1 11014 1 14409 9
Case 1: 9 Case 2: 736427
For the first sample input, all the 9 pairs of numbers are (1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (2, 3), (2, 5), (3, 4), (3, 5).
//分析:题目是要求a<=x<=b,c<=y<=d(其中a,c题目中已经说了必为1),中有多少对(x,y)(无序的)满足GCD(x,y)=k,那么可以转化成求(x,y)分别在区间1<=x<=b/k,1<=y<=d/k中有多少对满足GCD(x,y)=1; 转换b/=k,d/=k,之后,假设b<=d,那么我们可以分两步来求值:
1、求[1,b]与[1,b]之间有多少对数互质,显然就是phi[1]+phi[2]+...phi[b]即可,用线性求欧拉函数即可!
2\求[1,b]与[b+1,d]之间有多少对数互质,使用容斥定理
两步求值之和即为题意所求!
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=100000;
int q[N+5];
long long p[N+5];
int f(int a,int n)
{
int w[110],l=0;
for(int i=2;i*i<=n;i++)
{
if(n%i==0)
{
w[++l]=i;
while(n%i==0)n/=i;
}
if(n==1)break;
}
if(n!=1)w[++l]=n;
int sum=0;
for(int i=1;i< (1<<l);i++)
{
int flat=0,s=1;
for(int j=0;j<l;j++)
if(i&(1<<j))
{flat=!flat;
s*=w[j+1];
}
s=a/s;
if(flat)
sum+=s;
else
sum-=s;
}
return (a-sum);
}
int main()
{
memset(q,0,sizeof(q));
q[0]=q[1]=1;
int n=0;
for(int i=2;i<=N;i++)
{
if(!q[i])
{
for(int j=i;j<=N;j+=i)
{
if(!q[j])q[j]=j;
q[j]=q[j]/i*(i-1);
}
}
}
p[1]=1;
for(int i=2;i<=N;i++)
{
p[i]=p[i-1]+q[i];
}
int m,a,b,c,d,k;
int t,kase=0;
scanf("%d",&t);
while(t--)
{
long long ans;
scanf("%d%d%d%d%d",&a,&b,&c,&d,&k);
if(k==0||b<k||d<k)
ans=0;
else
{
b/=k;d/=k;
if(b>d)swap(b,d);
ans=0;
for(int i=b+1;i<=d;i++)
{int k=f(b,i);
//cout<<i<<" * "<<k<<endl;
ans+=k;
}
ans+=p[b];
}
printf("Case %d: %lld\n",++kase,ans);
}
return 0;
}