POJ 3904 Sky Code (容斥原理)

来源:互联网 发布:淘宝卖家货到付款流程 编辑:程序博客网 时间:2024/05/29 03:52

http://poj.org/problem?id=3904


题意,给出n个数,问有多少组(a,b,c,d)公约数为1,注意并不一定两两互质!

         总共情况: C(n , 4) 

           容斥原理应用,

          以2为因子的数有a个,3为因子 的数有b个,6为因子的数有c个,

          n个数不互质的四元组个数为C(a ,4)+C(b ,4)-C(4,c) 

          C(n , 4)  - ( 含奇数个素因子的个数,4) + C(偶数个素因子的个数 , 4)


typedef long long LL ;const int Max_N = 10008 ;vector<int> primefactor ;int  PrimeSum[Max_N] ;int  Bit[Max_N] ;void GetPrimFactor(int x){     primefactor.clear() ;     int i , N  , j  , m  , bit ;     for(i = 2 ; i * i <= x ; i++){           if(x % i == 0){                primefactor.push_back(i) ;                while(x % i == 0)                     x /= i ;           }     }     if(x != 1)          primefactor.push_back(x) ;     N = primefactor.size() ;     for(i = 1 ; i < (1<<N) ; i++){          m = 1 ;          bit = 0 ;          for(j = 0 ; j < N ; j++){                if(i & (1<<j)){                    bit++ ;                    m *= primefactor[j] ;                }          }          if(bit > 0){               PrimeSum[m]++ ;               Bit[m] = bit ;          }     }}LL  C4(int n){    LL N = LL(n) ;    return N*(N-1)*(N-2)*(N-3)/24 ;}LL Ans(int N){   int i , x ;   memset(PrimeSum , 0 , sizeof(PrimeSum)) ;   for(i = 1 ; i <= N ; i++){        scanf("%d" ,&x) ;        GetPrimFactor(x) ;   }   LL ans = C4(N) ;   for(i = 1 ; i <= 10000 ; i++){         if(PrimeSum[i]){              if(Bit[i]&1)                  ans -= C4(PrimeSum[i]) ;              else                  ans += C4(PrimeSum[i]) ;          }   }   return ans ;}int  main(){     int n ;     while(cin>>n){          cout<<Ans(n)<<endl ;     }     return 0 ;}



0 0
原创粉丝点击