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 }
代码君

 

你可能感兴趣的:(GC)