Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4291 Accepted Submission(s): 1502
前几天用容斥原理写过这题:
http://www.cnblogs.com/kuangbin/p/3269182.html
速度比较慢。
用莫比乌斯反演快很多。
莫比乌斯反演资料:
http://wenku.baidu.com/view/542961fdba0d4a7302763ad5.html
http://baike.baidu.com/link?url=1qQ-hkgOwDJAH4xyRcEQVoOTmHbiRCyZZ-hEJxRBQO8G0OurXNr6Rh6pYj9fhySI0MY2RKpcaSPV9X75mQv0hK
这题求[1,n],[1,m]gcd为k的对数。而且没有顺序。
转化之后就是[1,n/k],[1,m/k]之间互质的数的个数。
用莫比乌斯反演就很容易求了。
为了去除重复的,去掉一部分就好了;
这题求的时候还可以分段进行优化的。
具体看我的下一篇博客吧!
1 /* *********************************************** 2 Author :kuangbin 3 Created Time :2013/8/21 19:32:35 4 File Name :F:\2013ACM练习\专题学习\数学\莫比乌斯反演\HDU1695GCD.cpp 5 ************************************************ */ 6 7 #include <stdio.h> 8 #include <string.h> 9 #include <iostream> 10 #include <algorithm> 11 #include <vector> 12 #include <queue> 13 #include <set> 14 #include <map> 15 #include <string> 16 #include <math.h> 17 #include <stdlib.h> 18 #include <time.h> 19 using namespace std; 20 const int MAXN = 1000000; 21 bool check[MAXN+10]; 22 int prime[MAXN+10]; 23 int mu[MAXN+10]; 24 void Moblus() 25 { 26 memset(check,false,sizeof(check)); 27 mu[1] = 1; 28 int tot = 0; 29 for(int i = 2; i <= MAXN; i++) 30 { 31 if( !check[i] ) 32 { 33 prime[tot++] = i; 34 mu[i] = -1; 35 } 36 for(int j = 0; j < tot; j++) 37 { 38 if(i * prime[j] > MAXN) break; 39 check[i * prime[j]] = true; 40 if( i % prime[j] == 0) 41 { 42 mu[i * prime[j]] = 0; 43 break; 44 } 45 else 46 { 47 mu[i * prime[j]] = -mu[i]; 48 } 49 } 50 } 51 } 52 int main() 53 { 54 //freopen("in.txt","r",stdin); 55 //freopen("out.txt","w",stdout); 56 int T; 57 int a,b,c,d,k; 58 Moblus(); 59 scanf("%d",&T); 60 int iCase = 0; 61 while(T--) 62 { 63 iCase++; 64 scanf("%d%d%d%d%d",&a,&b,&c,&d,&k); 65 if(k == 0) 66 { 67 printf("Case %d: 0\n",iCase); 68 continue; 69 } 70 b /= k; 71 d /= k; 72 if(b > d)swap(b,d); 73 long long ans1 = 0; 74 for(int i = 1; i <= b;i++) 75 ans1 += (long long)mu[i]*(b/i)*(d/i); 76 long long ans2 = 0; 77 for(int i = 1;i <= b;i++) 78 ans2 += (long long)mu[i]*(b/i)*(b/i); 79 ans1 -= ans2/2; 80 printf("Case %d: %I64d\n",iCase,ans1); 81 } 82 return 0; 83 }