题目大意:
从1~b中取一个数作为x , 1~d中取一个数作为y
令gcd(x,y) = k 的取法有多少种
这里我们可以用莫比乌斯函数来解决问题
这里用到的公式是[gcd(x,y)==1] = Σ(del|gcd(x,y))mu(del)
Σ(1<=x<=b)Σ(1<=y<=d)[gcd(x,y)==k]
= Σ(1<=x<=b/k)Σ(1<=y<=d/k)[gcd(x,y)==1]
= Σ(1<=x<=b/k)Σ(1<=y<=d/k) Σ(del|gcd(x,y)) mu(del)
=Σ(1<=x<=b/k & del|x)Σ(1<=y<=d/k & del|y) mu(del)
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 5 using namespace std; 6 #define ll long long 7 #define N 100010 8 int mu[N] , prime[N] ; 9 bool check[N]; 10 11 void getMu(int n) 12 { 13 memset(check , 0 , sizeof(check)); 14 mu[1] = 1; 15 int tot = 0; 16 for(int i=2 ; i<=n ; i++){ 17 if(!check[i]){ 18 prime[tot++]=i; 19 mu[i] = -1; 20 } 21 for(int j=0 ; j<tot ; j++){ 22 if(i*prime[j]>n) break; 23 check[i*prime[j]] = true; 24 if(i % prime[j] == 0){ 25 mu[i*prime[j]] = 0; 26 break; 27 }else{ 28 mu[i*prime[j]] = -mu[i]; 29 } 30 } 31 } 32 } 33 34 int main() 35 { 36 int a , b , c , d , k , T , cas=0; 37 scanf("%d" , &T); 38 getMu(100000); 39 while(T--) 40 { 41 scanf("%d%d%d%d%d" , &a , &b , &c , &d , &k); 42 if(k == 0){ 43 printf("Case %d: 0\n" , ++cas); 44 continue; 45 } 46 a/=k , b/=k , c/=k , d/=k; 47 int maxn = b; 48 if(b<d){ 49 int t=b; 50 b=d , d=t; 51 maxn = b; 52 } 53 ll ans = 0; 54 for(int i=1 ; i<=maxn ; i++){ 55 int t1 = b/i , t2=d/i; 56 ans = ans+(ll)t1*t2*mu[i]; 57 } 58 59 //计算重复的 60 ll tmp = 0; 61 for(int i=1 ; i<=maxn ; i++){ 62 int t1 = d/i , t2 = d/i; 63 tmp = tmp+(ll)t1*t2*mu[i]; 64 } 65 ans = ans - (tmp-1)/2; 66 printf("Case %d: %lld\n" , ++cas , ans); 67 } 68 return 0; 69 }
我还在坚持,我还未达到我所想,梦~~一直在