POJ 3904 Sky Code (容斥原理)

题意:给定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;
}
时间: 2024-10-12 09:16:02

POJ 3904 Sky Code (容斥原理)的相关文章

POJ 3904 Sky Code (容斥+莫比乌斯反演)

Sky Code Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1831   Accepted: 570 Description Stancu likes space travels but he is a poor software developer and will never be able to buy his own spacecraft. That is why he is preparing to ste

poj 3904 Sky Code

点击打开链接 Sky Code Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1562   Accepted: 478 Description Stancu likes space travels but he is a poor software developer and will never be able to buy his own spacecraft. That is why he is preparing

[容斥原理] poj 3094 Sky Code

题目链接: http://poj.org/problem?id=3904 Sky Code Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1334   Accepted: 405 Description Stancu likes space travels but he is a poor software developer and will never be able to buy his own spacecraf

POJ 3904(容斥原理)

Sky Code Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1750   Accepted: 545 Description Stancu likes space travels but he is a poor software developer and will never be able to buy his own spacecraft. That is why he is preparing to ste

POJ Sky Code 莫比乌斯反演

N. Sky Code Time Limit: 1000ms Case Time Limit: 1000ms Memory Limit: 65536KB 64-bit integer IO format: %lld      Java class name: Main Submit Status Font Size: + - Stancu likes space travels but he is a poor software developer and will never be able

Sky Code(poj3904)

Sky Code Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2085   Accepted: 665 Description Stancu likes space travels but he is a poor software developer and will never be able to buy his own spacecraft. That is why he is preparing to ste

poj3904 Sky Code

Sky Code Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1694   Accepted: 523 Description Stancu likes space travels but he is a poor software developer and will never be able to buy his own spacecraft. That is why he is preparing to ste

【POJ 1850】 Code

[POJ 1850] Code 还是非常想说 数位dp真的非常方便! !. 数位dp真的非常方便!.! 数位dp真的非常方便! !! 重要的事说三遍 该题转换规则跟进制差点儿相同 到z时进一位 如az下位为bc 上位必须比下位小 依据这个规则搜出全部情况就可以 #include <iostream> #include <cstdio> #include <cstring> using namespace std; int dp[11][27]; int digit[11

POJ3094 Sky Code(莫比乌斯反演)

POJ3094 Sky Code(莫比乌斯反演) Sky Code 题意 给你\(n\le 10^5\)个数,这些数\(\le 10^5\),问这些这些数组成的互不相同的无序四元组(a,b,c,d)使得gcd(a,b,c,d)=1的四元组有多少? 解法 枚举一个约数\(k\),看看总共有多少个数\(S_k=\{x\}\)满足\(k|x\).那么可以保证(a,b,c,d)有的一个共同的因子是k,这样的四元组的个数就是 \[ F(k)={|S_k|\choose 4} \] 这样算会算重,比如枚举到