hdu1695 GCD

  http://acm.hdu.edu.cn/showproblem.php?pid=1695
1
/** 2 大意: a<=x<=b , c<= y <= d ,求在此範圍內 有多少組x,y 知足 gcd(x,y) = k ; a=c=1(題目有問題)gcd(x,y),gcd(y,x) 算一個 3 思路: 也就是求 1 - - b/k, 1 -- d/k 內有多少個數互素, 4 一、 若k =0, 則 res =0, 由於任何兩個數的gcd 不可能爲 0 5 二、 若k !=0 , 設b = b/k, d = d/k, 默認 d>b 那麼 6 對於1-b 之間的互質的數 就是歐拉函數, 7 對於b+1 -- d 從b+1 -- d 之間找一個數y, 在 1 - b 之間尋找與其互質的數。 那麼 1 -b 之間的數 確定不含有y的質因子, 那麼將y 質因數分解, 在 1 -- b 之間的數,中除掉 含有 y因子的數(注意這裏不僅是質因子,是y全部的因子)。。 剩下的即爲所求。。 8 --------------------------------------------------------------------------------- 9 別人的解釋 10 求[1..b]中的x和[1..d]中的y有多少gcd(x,y) = k. 11 要求gcd(x,y) = k,則等價於求 gcd(x/k,y/k) = 1.因此問題轉化成求[1..b/k]和[1..d/k]中有多少對gcd(x,y) = 1. 12 13 進一步轉換成 枚舉[1,d]區間裏的n與][1, b]的區間的數互質的個數,這裏d>=b. 14 由於[1,b]包含在[1,d]裏,因此[1,b]至關於累加歐拉函數phi(i)的值,而[b + 1, d]這個區間能夠經過容斥原理來求出. 15 要求n與][1, b]的區間的數互質的個數,能夠考慮求與n不互質數的個數v, 那麼互質的數天然就是b - v. 16 因此分解n的素因子,考慮n的素因子pi,則[1, b]中與pi不互質的數的個數是[b/pi](即其multiples). 17 若是這樣累加[b/pi]的話則會加上不少重複的值(一個數可能有多個素因子),這裏容斥原理就派上用場了. 18 ------------------------------------------------------------------------------------- 19 20 **/ 21 22 #include <iostream> 23 #include <cmath> 24 #include <algorithm> 25 #include <cstring> 26 #include <cstdio> 27 using namespace std; 28 const long long maxn = 100050; 29 long long phi[maxn]; 30 long long priD[maxn]; 31 long long len; 32 33 void euler(long long n){ 34 len =0; 35 long long m = (long long )sqrt(n+0.5); 36 for(int i=2;i<=m;i++) if(n%i==0){ 37 priD[len++] = i; 38 while(n%i==0) 39 n = n/i; 40 } 41 if(n>1) 42 priD[len++] = n; 43 } 44 45 void phi_table(){ 46 for(int i=2;i<maxn;i++) 47 phi[i] =0; 48 phi[1] =1; 49 for(int i=2;i<maxn;i++)if(!phi[i]){ 50 for(int j=i;j<maxn;j+=i){ 51 if(!phi[j]) phi[j] =j; 52 phi[j] = phi[j] /i *(i-1); 53 } 54 } 55 } 56 57 long long solve(long long n){ 58 long long sum =0; 59 for(long long i=1;i<1ll<<len;i++){ 60 long long tmp =1; 61 long long flag =0; 62 for(int j =0;j<len;j++){ 63 if(i&(1ll<<j)){ 64 flag ++; 65 tmp *= priD[j]; 66 } 67 } 68 if(flag%2) 69 sum += n/tmp; 70 else 71 sum -= n/tmp; 72 } 73 return sum; 74 } 75 76 int main() 77 { 78 phi_table(); 79 int t; 80 cin>>t; 81 int cnt; 82 long long a,b,c,d,k; 83 for(cnt =1;cnt<=t;cnt++){ 84 cin>>a>>b>>c>>d>>k; 85 if(k==0){ 86 cout<<"Case "<<cnt<<": "<<0<<endl; 87 continue; 88 } 89 b = b/k; 90 d = d/k; 91 if(b>d){ 92 swap(b,d); 93 } 94 long long res =0; 95 for(int i=1;i<=b;i++) 96 res += phi[i]; 97 for(int i=b+1;i<=d;i++){ 98 euler(i); 99 res += (b - solve(b)); 100 } 101 cout<<"Case "<<cnt<<": "<<res<<endl; 102 } 103 return 0; 104 }
相關文章
相關標籤/搜索