POJ 3904 Sky Code (容斥原理)

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值