GCD
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4825 Accepted Submission(s): 1729
Problem Description
Given 5 integers: a, b, c, d, k, you're to find x in a...b, y in c...d that GCD(x, y) = k. GCD(x, y) means the greatest common divisor of x and y. Since the number of choices may be very large, you're only required to output the total number of different number pairs.
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.
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.
Input
The input consists of several test cases. The first line of the input is the number of the cases. There are no more than 3,000 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.
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.
Output
For each test case, print the number of choices. Use the format in the example.
Sample Input
2 1 3 1 5 1 1 11014 1 14409 9
Sample Output
Case 1: 9 Case 2: 736427HintFor 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).
Source
给你5个数,a,b,c,d,k在[a,b]区间找一个数x,在[c,d]区间找一个数y,使得(x,y)的最大公约数是k。找出所有满足条件的不同的(x,y)的对数。
要求两个集合(1...b, 1...d)中有多少对数的最大公约数为k,此问题等价于求两个集合(1...b/k,1...d/k)中有多少对数互质。假设b/k<d/k。
题目可以分两部分求解,第一部分就是求1~b之间有多少对数互质,即求欧拉函数。第二部分求b+1~d之间每一个数与1~b之间有多少数互质。对于(b+1~d)中的每一个y,要想知道(1~b)中有多少数与它互质,我们只需要知道多少个数与它不互质即可。而两个数不互质就意味着它们有公因子。对于每一个y的因子f,都能确定地知道(1~b)中有多少个数含有因子f,用容斥原理算一下,就能知道(1~b)中有多少个数与y互质了。
//171MS 9240K
#include<stdio.h>
#include<string.h>
#define M 100007
long long phi[M];
int prime[M][20],num[M];//prime[i][j]存储的是i的第j个因子,num[i]存i的质因子个数
void getphi()//求欧拉函数
{
memset(num,0,sizeof(num));
for(int i=1;i<M;i++)
phi[i]=i;
for(int i=2;i<M;i++)
if(phi[i]==i)
{
phi[i]=i-1;//质数的欧拉函数是它本身-1
for(int j=i<<1;j<M;j+=i)//求欧拉函数和质因子数
phi[j]=phi[j]-phi[j]/i,prime[j][num[j]++]=i;
}
for(int i=2;i<M;i++)
phi[i]+=phi[i-1];
}
int dfs(int a,int b,int n)
{
if(!b)return 0;
int count=0;
for(int i=a;i<num[n];i++)
count+=b/prime[n][i]-dfs(i+1,b/prime[n][i],n);
return count;//返回在1~b之间与n不互质的个数
}
int main()
{
getphi();
int t,cas=1;
scanf("%d",&t);
while(t--)
{
int a,b,c,d,k,flag;
scanf("%d%d%d%d%d",&a,&b,&c,&d,&k);
printf("Case %d: ",cas++);
if(!k){printf("0\n");continue;}//如果k=0,则输出0
b/=k;
d/=k;
if(b>d){flag=b;b=d;d=flag;}
long long ans=phi[b];//求1~b中的gcd为1的个数
for(int i=b+1;i<=d;i++)//求b+1~d中与1~b中gcd为1的个数
ans+=b-dfs(0,b,i);//容斥原理
printf("%I64d\n",ans);//杭电不认%lld,坑~~
}
return 0;
}