hdu1695GCD
GCD
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4737 Accepted Submission(s): 1693
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: 736427
Hint
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).
Source
// 在(1,b),(1,d)里面各取一个数 使得gcd(x,y) == k
//即 n*k == x && m*k == y && gcd(x,y) == 1 ;
//移项 n = x/k , m = y/k ; 所以转化为在 (1,b/k),和(1,d/k)各取一个数
//使得这两个数互素有多少种取法 令 n = b/k , m = d/k , n <= m
//因为(s,e)和(e,s)是相同的,所以我们可以枚举 m ,设枚举到 y
// 在 y <= n 时,和y 互素的就是 phi[y] 了,在 y > n 时 就比较麻烦、
// 我们可以把 y 分解成 p1^x1*p2^x2*p3^x3 。。。然后求(1,n) 中和 y不互素的数
// 也就是把(1,n) 中 p1,p2,p3.。。的倍数给去掉,去掉的时候会重复,就需要用到容斥定理来求
//即 n*k == x && m*k == y && gcd(x,y) == 1 ;
//移项 n = x/k , m = y/k ; 所以转化为在 (1,b/k),和(1,d/k)各取一个数
//使得这两个数互素有多少种取法 令 n = b/k , m = d/k , n <= m
//因为(s,e)和(e,s)是相同的,所以我们可以枚举 m ,设枚举到 y
// 在 y <= n 时,和y 互素的就是 phi[y] 了,在 y > n 时 就比较麻烦、
// 我们可以把 y 分解成 p1^x1*p2^x2*p3^x3 。。。然后求(1,n) 中和 y不互素的数
// 也就是把(1,n) 中 p1,p2,p3.。。的倍数给去掉,去掉的时候会重复,就需要用到容斥定理来求
#include<iostream> #include<algorithm> #include<cmath> #include<cstring> #include<cstdio> #include<vector> using namespace std; #define maxn 100010 #define LL long long LL phi[maxn] ; vector<int>qe[maxn] ; void init() { int n , i ; n = maxn-10 ; for( i = 1 ; i <= n ;i++)phi[i] = i ; for( i = 2 ; i <= n ;i++)if(phi[i] == i ) { for( int j = i ; j <= n ;j += i ){ phi[j] = phi[j]*(i-1)/i; qe[j].push_back(i) ; } } for( i = 2 ; i <= n ;i++ ) phi[i] = phi[i]+phi[i-1] ; } LL dfs( int x , int n , int now ) { int i ; LL ret = 0 ; for( i = x ; i < qe[now].size() ; i++ ) { ret += n/qe[now][i]-dfs(i+1,n/qe[now][i],now) ; } return ret ; } int main() { int i , n , m ,num ,k , T , case1 = 0 ; int a , b , c , d , e ; LL ans ; init() ; // freopen("in.txt","r",stdin) ; cin >> T ; while(T--) { cin >> a >> b >> c >> d >> k ; if(k == 0) { printf("Case %d: ",++case1) ; puts("0") ; continue ; } if( b > d ) swap(d,b) ; n = b/k ; m = d/k ; ans = phi[n] ; for( i = n+1 ; i <= m ;i++ ) { if(phi[i] == i-1) ans += n ; else ans += n-dfs(0,n,i) ; } printf("Case %d: ",++case1) ; cout << ans << endl; } return 0 ; }