hdoj 5072 Coprime 【想法+容斥原理】

题目:hdoj 5072 Coprime

题意:给出n个数,然后让你从其中任意选出三个数满足其中三个数都互质或者都不互质,让你求满足这样选择条件的选择种数。

分析:首先我们从反面考虑这个问题,一个满足条件的选择{ a , b , c },题目要求[(a, b) = (b, c) = (a, c) = 1] or [(a, b) ≠ 1 and (a, c) ≠ 1 and (b, c) ≠ 1],其中(a,b)是a和b的最大公约数。

那么其反面就是,[(a, b) = (b, c) =1 and (a, c)
 ≠1] or [(a, b) = 1 and (a, c) ≠ 1 and (b, c) ≠ 1],即其中三个元素的组合两种互质,一种不互质或者两种不互质,一种互质。那么当其中一个数 a 固定的时候,另外两个元素的选择只能是一个与 a 互质,一个不互质。

既然这样我们就可以转化为快速求序列中一个数 x 与其他数互质数的个数,不互质 = n - 互质 - 1(当前元素).

这时候就用到容斥原理,对于一个数 x ,我们首先分解质因子。比如30 ,质因子有2,3,5

那么与其互质的数的个数 = num【2】 + num【3】 + num【5】 - num【2*3】 - num【2*5】 - num【3*5】 + num【2*3*5】

其中num【x】 表示在整个序列中以 x 为因子的数的个数。

这样就可以解了

是一个质量比较高的题目,不止考数学,思想,编码的时候要用到状态压缩,所以是一道质量相当高的题目

AC代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <map>
#include <vector>
#include <queue>
#include <stack>
using namespace std;
const int N = 101000;

int num[N];
int fact[N];
bool vis[N];

bool test(int x)  ///素数测试
{
    if(x==1)
        return false;
    for(int i=2;i*i<=x;i++)
    {
        if(x%i==0)
            return false;
    }
    return true;
}
long long solve(int n)
{
    long long ans = 0;
    for(int i=0;i<n;i++)
    {
        int res = 0,tmp = num[i];
        vector<int> v;
        for(int j=2;j*j<=tmp;j++)  ///分解素因子
        {
            if(tmp%j==0)
            {
                v.push_back(j);
                while(tmp%j==0)
                    tmp/=j;
            }
        }
        if(test(tmp))
            v.push_back(tmp);
        for(int st = 1;st<(1<<v.size());st++)
        {
            int pps = 0,kks = 1;
            for(int j=0;j<v.size();j++)
            {
                if(st&(1<<j)){
                    pps++;
                    kks *= v[j];
                }
            }
            if(pps&1)
                res+=fact[kks];
            else
                res-=fact[kks];
        }
        if(res==0)
            continue;
        ans+=(long long)(res-1)*(n-res);
        v.clear();
    }
    return ans/2;
}
int main()
{
    //freopen("Input.txt","r",stdin);
    int n,T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        memset(vis,false,sizeof(vis));
        memset(fact,0,sizeof(fact));
        for(int i=0;i<n;i++){
            scanf("%d",&num[i]);
            vis[ num[i] ] = true;
        }
        for(int i=2;i<N;i++)
        {
            for(int j=i;j<N;j+=i)
            {
                if(vis[j])
                    fact[i]++;
            }
        }
        long long count = (long long)n * (n-1) * (n-2);
        count/=6;
        printf("%lld\n",count-solve(n));
    }
    return 0;
}
时间: 2024-10-12 12:34:47

hdoj 5072 Coprime 【想法+容斥原理】的相关文章

ACM学习历程—HDU 5072 Coprime(容斥原理)

Description There are n people standing in a line. Each of them has a unique id number. Now the Ragnarok is coming. We should choose 3 people to defend the evil. As a group, the 3 people should be able to communicate. They are able to communicate if

hdu 5072 Coprime(数论)

题目链接:hdu 5072 Coprime 题目大意:给定N个数,问能选出多少个3元组,要么[(a, b) = (b, c) = (a, c) = 1] or [(a, b) ≠ 1 and (a, c) ≠ 1 and (b, c) ≠ 1]. 解题思路:这题可以换个角度想,可以将三个数看做三角形的三条边,互质即边的颜色为1,否则为0,那么要求的即为 三条边颜色相同的三角形有多少个. 总的三角形的个数可求,那么如果求出三条边不完全相同的三角形个数,相减一下即可. 枚举顶点,然后确定以该点形成的

HDU 5072 Coprime (单色三角形+容斥原理)

题目链接:Coprime 题面: Coprime Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 1181    Accepted Submission(s): 471 Problem Description There are n people standing in a line. Each of them has a uniq

HDOJ 4135 Co-prime 容斥原理

求得n的因数后,简单容斥 Co-prime Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1798    Accepted Submission(s): 685 Problem Description Given a number N, you are asked to count the number of integers bet

HDU 5072 Coprime (单色三角形问题+容斥原理)

我们先来介绍一下单色三角形问题,如下 单色三角形 在空间中给出了n个点.这些点任三点不共线,并且每两个点之间都有一条线相连,每一条线不是红的就是黑的.在这些点和线组成的三角形中,如果一个三角形的三条边的颜色都相同,那么我们就称这个三角形为单色三角形.现给出所有涂红色的线,试求出单色三角形的数目. 任务: 请写一个程序: 从文本文件中读入点数和对红色连线的描述: 找出该图中红色三角形的数目: 把结果输出到文件TRO.OUT中. 输入格式: 在文本文件TRO.IN的第一行包括一个整数n,3 <= n

hdu 5072 Coprime 容斥原理

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 1509    Accepted Submission(s): 592 Problem Description There are n people standing in a line. Each of them has a unique id number. Now the Ragn

[容斥原理] hdu 5072 Coprime

题意: 给n个数,求这n个数取3个数构成一个集合, 这三个数两两互质或者两两不互质,为有多少种取法. 思路: 首先这可以转换成一个单色三角形的问题. 就是三个数为三角形的三个顶点,两个顶点如果互质则边为1,不互质边为0 为三条边均为1或者均为0的三角形就多少个. 因为三角形的总数我们是知道的,然后我们取对立面算. 那么其实我们可以枚举顶点,然后求出每个数在这些数中和它互质的有多少个,不互质的有多少个 然后各取一个就是我们要的三角形了. 我们假设互质的有X个,不互质的有Y个 那么以Z为顶点的三角形

hdu 5072 Coprime(同色三角形+容斥)

pid=5072">http://acm.hdu.edu.cn/showproblem.php?pid=5072 单色三角形模型 现场赛和队友想了3个小时,最后发现想跑偏了.感觉好可惜的一道题,要是知道这个模型....就能够轻松的拿银了啊. . . 题意不再赘述,就是求同色三角形的个数.总的三角形的个数是C(n,3),仅仅需减去不同色的三角形就可以.对于每一个点(数),与它互质的连红边,不互质的连蓝边,那么对于该点不同色三角形个数为蓝边数*红边数/2,由于同一个三角形被计算了两次. 那么同

hdu 5072 Coprime (容斥)

Problem Description There are n people standing in a line. Each of them has a unique id number. Now the Ragnarok is coming. We should choose 3 people to defend the evil. As a group, the 3 people should be able to communicate. They are able to communi