SWJTU 2212 简单的GCD (莫比乌斯反演)

简单的GCD

Time Limit:1000MS  Memory Limit:32768K
Total Submit:12 Accepted:4

Description

问题很简单(洁),有 T 个询问,每次询问 a,b,d ,问有多少对 (x,y) 满足 1 ≤ x ≤ a, 1 ≤ y ≤ b ,且 Gcd(x,y) = d 。
注意这里(x=1, y=2)与(x=2, y=1)认为是一对。

Input

输入第一行为T,表示测试数据组数。
下面的T行,每行包括三个整数a,b,d。
1 ≤ d ≤ a,b ≤ 100000, 1 ≤ T ≤ 3000。

Output

输出为Case的形式,详见样例

Sample Input

 

2
3 5 1
41 18467 20

 

Sample Output

 

Case 1: 9
Case 2: 1384

 

Hint

第一组样例有以下9对满足条件(1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (2, 3), (2, 5), (3, 4), (3, 5).

 

 

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<string>
 5 #include<queue>
 6 #include<algorithm>
 7 #include<map>
 8 #include<iomanip>
 9 #include<climits>
10 #include<string.h>
11 #include<numeric>
12 #include<cmath>
13 #include<stdlib.h>
14 #include<vector>
15 #include<stack>
16 #include<set>
17 #define FOR(x, b, e)  for(int x=b;x<=(e);x++)
18 #define REP(x, n)     for(int x=0;x<(n);x++)
19 #define INF 1e7
20 #define MAXN 1000010
21 #define maxn 100010
22 #define Mod 1000007
23 #define N 1010
24 using namespace std;
25 typedef long long LL;
26 
27 
28 bool vis[MAXN];
29 int prime[MAXN],mu[MAXN];
30 LL ans, cnt;
31 
32 void init()
33 {
34     memset(vis,0,sizeof(vis));
35     mu[1] = 1;
36     int tot = 0;
37     for(int i=2; i<MAXN; i++)
38     {
39         if(!vis[i])
40         {
41             prime[tot++] = i;
42             mu[i] = -1;
43         }
44         for(int j=0; j<tot && i*prime[j]<MAXN; j++)
45         {
46             vis[i*prime[j]] = 1;
47             if(i%prime[j]) mu[i*prime[j]] = -mu[i];
48             else
49             {
50                 mu[i*prime[j]] = 0;
51                 break;
52             }
53         }
54     }
55 }
56 
57 int T;
58 int kase = 1;
59 int x, y, d;
60 
61 void run()
62 {
63 
64     scanf("%d%d%d", &x, &y, &d);
65     x /= d;
66     y /= d;
67     if (x > y) swap(x,y);
68     ans = 0;
69     cnt= 0;
70     for (int i = 1;i <= x;++ i) {
71         ans += (LL)mu[i]*(x/i)*(y/i);
72         cnt += (LL)mu[i]*(x/i)*(x/i);
73 
74     }
75     ans -= cnt/2;
76     printf("Case %d: %lld\n", kase++, ans);
77 }
78 
79 int main()
80 {
81     init();
82     cin >> T;
83     while (T--)
84         run();
85     return 0;
86 }
代码君

 

posted @ 2015-03-30 20:38  UsedRose  阅读(130)  评论(0编辑  收藏  举报