题意:http://hzwer.com/4205.html
同hdu1695
1 #include <iostream> 2 #include <cstring> 3 #include <cmath> 4 #include <cstdio> 5 using namespace std; 6 #define LL long long 7 #define MMX 50010 8 int mu[MMX],msum[MMX]; 9 LL n; 10 bool check[MMX]; 11 int prime[MMX]; 12 13 void Moblus() //莫比乌斯反演,mu[i]为莫比乌斯函数 14 { 15 memset(check,false,sizeof(check)); 16 mu[1] = 1; 17 int tot = 0; 18 for(int i = 2; i <= MMX; i++) 19 { 20 if( !check[i] ) 21 { 22 prime[tot++] = i; 23 mu[i] = -1; 24 } 25 for(int j = 0; j < tot; j++) 26 { 27 if(i * prime[j] > MMX) break; 28 check[i * prime[j]] = true; 29 if( i % prime[j] == 0) 30 { 31 mu[i * prime[j]] = 0; 32 break; 33 } 34 else 35 { 36 mu[i * prime[j]] = -mu[i]; 37 } 38 } 39 } 40 msum[1]=mu[1]; //求和,求G的时候用 41 for (int i=2;i<=MMX;i++) 42 msum[i]=msum[i-1]+mu[i]; 43 } 44 45 LL G(int n,int m) //G(x,y)表示有多少组x<=n,y<=m,且x,y互质 ((x,y)和(y,x)算两组) 46 { 47 LL ans = 0; 48 if(n > m) swap(n,m); 49 for(int i = 1, la = 0; i <= n; i = la+1) 50 { 51 la = min(n/(n/i),m/(m/i)); 52 ans += (LL)(msum[la] - msum[i-1])*(n/i)*(m/i); //事先预处理:msum[n]=SUM(mu[1..n]) 53 } 54 return ans; 55 } 56 57 int main() 58 { 59 int T; 60 cin>>T; 61 Moblus(); 62 for (int zy=1; zy<=T; zy++) 63 { 64 int a,b,c,d,k; 65 //cin>>b>>d>>k; 66 scanf("%d%d%d ",&b,&d,&k); 67 if (b>d) swap(b,d); //assume b<d 68 b=b/k; 69 d=d/k; 70 71 LL ans1 = G(b,d); 72 73 printf("%lld ",ans1); 74 } 75 }
1020 | root | 1003 | Accepted | 564K | 3819MS | G++ | 1.62K | 2014-11-16 18:08:01 |