hdu 5072 计数+容斥原理

/*
题意: 给出n个数(n<100000), 每个数都不大于100000,数字不会有重复。现在随意抽出3个,问三个彼此互质 或者 三个彼此不互质的数目有多少。
思路: 这道题的原型是同色三角形, 可能现场很多队伍都知道这个模型, 所以这道题当时过的队伍还是挺多的。
这道题反着想,就是三个数中只有一对互质 或者只有两对互质的个数。
研究后发现 对于每个数字求出与其不互质的个数k   那么  sum ( k*(n-1-k) )/2 就是相反的数目, 所以最终的答案就是 C(n,3) -  sum ( k*(n-1-k) )/2.
*/
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

typedef __int64 LL;
const int maxn=1000;
int prime[maxn],flag[maxn],num;
int numc[maxn*100+5],f[maxn*100+5];
int factor[20],fac;
LL sum;

void getprimes()
{
    memset(flag,1,sizeof(flag));
    int i,j;num=0;
    for(i=2;i<maxn;i++)
    {
        if(flag[i]) prime[num++]=i;
        for(j=0;j<num && prime[j]*i<maxn;j++)
        {
            flag[prime[j]*i]=0;
            if(i%prime[j]==0) break;
        }
    }
}

void dfs1(int now,int s)//找出它所有的因子
{
    if(now==fac)
    {
        numc[s]++;
        return ;
    }
    dfs1(now+1,s);
    dfs1(now+1,s*factor[now]);
}

void dfs2(int id,int all,int now,int s )
{
    if(now==all)
    {
        sum+=numc[s];
        return ;
    }
    if(id<fac)
    {
        dfs2(id+1,all,now+1,s*factor[id]);
        dfs2(id+1,all,now,s);
    }
}

void getfactors(int n)//分解质因子
{
    int i;fac=0;
    for(i=0;i<num && prime[i]<=n;i++)
    {
        if(n%prime[i]==0)
        {
            factor[fac++]=prime[i];
            while(n%prime[i]==0) n/=prime[i];
        }
    }
    if(n>1) factor[fac++]=n;
}

int main()
{
    getprimes();
    int t,n,i,j;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        memset(numc,0,sizeof(numc));
        for(i=1;i<=n;i++)
        {
            scanf("%d",f+i);
            getfactors(f[i]);
            dfs1(0,1);
        }
        LL ans=0;
        for(i=1;i<=n;i++)
        {
            getfactors(f[i]);
            LL ret=1,temp=0;
            for(j=1;j<=fac;j++)//容斥原理找出与它不互质的个数
            {
                sum=0;
                dfs2(0,j,0,1);
                temp+=ret*sum;
                ret=-ret;
            }
            if(temp==0) continue;//当f[i]==1时,所有数都与它不互质的是0个
            ans+=(temp-1)*(n-temp);
        }
        printf("%I64d\n",(LL)n*(n-1)*(n-2)/6-ans/2);
    }
    return 0;
}
时间: 2024-10-13 03:09:22

hdu 5072 计数+容斥原理的相关文章

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(数论)

题目链接: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

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

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

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

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

2014 ACM Regional hdu 5072

ACM退役两年了, 没想到今年机缘巧合能去鞍山参加Regional了. 记得第一次参加Regional的时候那个心情很激动,激动的很难描述出来.而这次参加Regional一点压力都木有,感觉比参加省赛都轻松,甚至就像是在做练习赛似的.由于本来水平就不高,又隔了两年,所以毫无悬念地拿了个铜牌. 比赛时候C题基本已经想到了解法,由于时间的原因,没能过掉. C题现在在hdu的5072题. 题意: 给出n个数(n<100000), 每个数都不大于100000,数字不会有重复.现在随意抽出3个,问三个彼此

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

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

HDU 2461 Rectangles#容斥原理

http://acm.hdu.edu.cn/showproblem.php?pid=2461 题目很简单,但是由于询问数M可以很大,所以容易超时,这道题学到了在结构体里面写函数的方法,这样子效率更高,否则的话,这道题就TLE了. 根据容斥原理,先把每个小长方形的面积加上,然后看有没有与该小长方形相交的,用dfs实现,当相交面积为0时,则不进行dfs,且同样遵循奇加偶减(但代码里因为是以第二个作为depth=1开始进行dfs的,所以是奇减偶加). AC代码: #include<iostream>