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 }