码迷,mamicode.com
首页 > 其他好文 > 详细

POJ 3904 Sky Code (容斥原理)

时间:2016-04-04 22:43:55      阅读:165      评论:0      收藏:0      [点我收藏+]

标签:

题意:给定n个数,从n个数找出四个数,使这四个数的最大公约数为1,找出有多少对这样的组合。

   找最大公约数不是1的有多少对。

题解:四个数的公约数为1,并不代表四个数两两互质。比如(2,3,4,5)公约数为1,但是

   2和4并不互质。从反面考虑,先求出四个数公约数不为1的情况个数,用总的方案个数

   减去四个数公约数不为1的情况个数就是所求。

   求四个数公约数不为1的情况个数,需要将N个数每个数质因数分解,纪录下所有不同

   的素因子所能组成的因子(就是4个数的公约数),并统计构成每种因子的素因子个数,

   和因子总数。然后再计算组合数。比如说因子2的个数为a,则四个数公约数为2的个数

   为C(a,4),因子3的个数为b,则四个数公约数为3的个数为C(b,4),因子6(2*3)的个

   数为c,则四个数公约数的个数为C(c,4)。

   但是公约数为2的情况中或者公约数为3的情况中可能包括公约数为6的情况,相当于几

   个集合求并集,这就需要容斥定理来做。

   容斥原理应用,以2为因子的数有a个,3为因子 的数有b个,6为因子的数有c个,

   n个数不互质的四元组个数为C(4,a)+C(4,b)-C(4,c) (含奇数个素因子的加,偶数个素因子的减),

   下面就是统计出2,3,5这些因子的倍数的个数,对C(4,a)容斥!

代码:弄清思路以后就很好做了,一环扣一环,用二进制进行枚举,很棒!

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <math.h>
#include <stdlib.h>
using namespace std;
typedef long long ll;
ll c(ll n)
{
    return n*(n-1)*(n-2)*(n-3)/24;
}
ll f[10010],cnt,ccount[10010],num[10010];
void div(ll n)
{
    cnt=0;
    for(int i=2;i<=sqrt(n);i++)
    {
        if(n%i==0)
        f[cnt++]=i;
        while(n%i==0)
        n/=i;
    }
    if(n!=1)
    f[cnt++]=n;
}
void solve(ll n)
{
    div(n);
    for(int i=1;i<(1<<cnt);i++)
    {
        ll tmp=1,flag=0;
        for(int j=0;j<cnt;j++)
        {
            if(i&(1<<j))
            {
                flag++;
                tmp*=f[j];
                if(tmp>n)
                break;
            }
        }
        ccount[tmp]++;  //count是关键字 不能用
        num[tmp]=flag;
    }
}
int main()
{
    ll n,m;
    while(scanf("%lld",&n)!=EOF)
    {
        memset(ccount,0,sizeof(ccount));
        for(int i=0;i<n;i++)
        {
            scanf("%lld",&m);
            solve(m);
        }
        ll ans=c(n);
        for(int i=0;i<=10000;i++)
        {
            if(ccount[i])
            {
                if(num[i]&1)
                ans-=c(ccount[i]);
                else
                ans+=c(ccount[i]);
            }
        }
        printf("%lld\n",ans);
    }
    return 0;
}

 

POJ 3904 Sky Code (容斥原理)

标签:

原文地址:http://www.cnblogs.com/Ritchie/p/5352940.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!