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

原创 2015年07月09日 13:10:08

题目链接: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 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 and only if their id numbers are pairwise coprime or pairwise not coprime. In other words, if their id numbers are a, b, c, then they can communicate if and only if [(a, b) = (b, c) = (a, c) = 1] or [(a, b) ≠ 1 and (a, c) ≠ 1 and (b, c) ≠ 1], where (x, y) denotes the greatest common divisor of x and y.

We want to know how many 3-people-groups can be chosen from the n people.
 

Input
The first line contains an integer T (T ≤ 5), denoting the number of the test cases.

For each test case, the first line contains an integer n(3 ≤ n ≤ 105), denoting the number of people. The next line contains n distinct integers a1, a2, . . . , an(1 ≤ ai ≤ 105) separated by a single space, where ai stands for the id number of the i-th person.
 

Output
For each test case, output the answer in a line.
 

Sample Input
1 5 1 3 9 10 2
 

Sample Output
4
 

Source
2014 Asia AnShan Regional Contest

解题:
    题意求找出三数互质或都不互质的组数,直接肯定不行。此题原型为单色三角形,结果为C(3,n)-res,其中res为每个与每个数互质和不互质数量的乘积的累加。求与每个数不互质的数量,用到了容斥原理。看似简单的原理应用却这么广泛,如果没做过容斥原理的题目,可以先试一下HDU 1796。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
bool status[100010];
int factor[100010][8];
int store[100010],cnt[100010];
long long ans[100010],res;
int one_amount[300];
int refl[300][8];
int cal[8];
void prep()
{
    memset(refl,0,sizeof(refl));
    int cont=0,temp;
   for(int i=0;i<256;i++)
   {
       temp=i;
       one_amount[i]=cont=0;
       while(temp)
       {
         if(temp%2)
         {
             one_amount[i]++;
             refl[i][cont]=1;
         }
         cont++;
         temp/=2;
       }
   }
}
bool is_prime(int a)
{
	if(a<=3)return true;
	int x=sqrt(1.0*a);
	for(int i=2;i<=x;i++)
	{
		if(a%i==0)
			return false;
	}
	return true;
}
long long C(int x,int y)
{
	long long res=1;
	for(int i=1;i<=x;i++)
	{
		res=res*(y-i+1)/i;
	}
	return res;
}
int main()
{
	int t,n,p,tmp;
	long long temp;
	scanf("%d",&t);
	prep();
	while(t--)
	{
		res=0;
		memset(status,0,sizeof(status));
		memset(factor,0,sizeof(factor));
		memset(cnt,0,sizeof(cnt));
		memset(ans,0,sizeof(ans));
		scanf("%d",&n);
		for(int i=0;i<n;i++)
			scanf("%d",&store[i]);
		for(int i=0;i<n;i++)
			status[store[i]]=1;
        for(int i=2;i<=100000;i++)
		{
	       if(is_prime(i))
		   {
			   for(int j=i;j<=100000;j+=i)
			   {
				   if(status[j])
				   {
					   cnt[i]++;
				   }
				   p=0;
				   while(factor[j][p])
				   {
					   p++;
				   }
				   factor[j][p]=i;
			   }
		   }
		   else
		   {
             for(int j=i;j<=100000;j+=i)
			   {
				   if(status[j])
				   {
					   cnt[i]++;
				   }
			   }

		   }
		}
        for(int i=0;i<n;i++)
		{
           tmp=store[i];
           p=0;
		   while(factor[tmp][p])
		   {
			   cal[p]=factor[tmp][p];
			   p++;
		   }
		   if(p==0)
		   {
			   ans[i]=0;
			   continue;
		   }
           tmp=1<<p;
		   for(int j=1;j<tmp;j++)
           {
              temp=1;
              for(int k=0;k<p;k++)
              {
                  if(refl[j][k])
                 {
                    temp=temp*cal[k];
                 }
			   }
              if(one_amount[j]%2)
              ans[i]+=cnt[temp];
              else
              ans[i]-=cnt[temp];
          }
		   ans[i]-=1;
		}
		for(int i=0;i<n;i++)
		{
			res+=(ans[i]*(n-ans[i]-1));
		}
		res/=2;
		printf("%I64d\n",C(3,n)-res);
	}
	return 0;
}

总结:
用好容斥原理的关键在于,搞清楚集合的交的含义。
 

版权声明:欢迎交流!

hdu5072 Coprime | 2014鞍山赛区C题 | 容斥原理

容斥原理
  • csuhoward
  • csuhoward
  • 2015年04月10日 13:47
  • 1933

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

Coprime Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Tota...
  • qq_24451605
  • qq_24451605
  • 2015年03月23日 22:35
  • 589

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

单色三角形问题,HDU5072 Coprime
  • u013790563
  • u013790563
  • 2014年11月03日 19:13
  • 881

hdu 5072 Coprime 容斥 同色三角形

n个点之间都有边相连颜色为红或黑, 那对于每个点能形成异色三角形的方案为blackEdge[i] * redEdge[i] ,这n个点能形成异色三角形的方案数为 sum (blackEdge[i] *...
  • acblacktea
  • acblacktea
  • 2016年08月30日 22:16
  • 239

hdu 2597(容斥原理)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5297; 题意:给出n和r,求数列Y的第n个元素是多少。其中数列Y是正整数数列去除a^b(2 分析:...
  • qq_27599517
  • qq_27599517
  • 2016年07月01日 20:38
  • 1750

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

http://acm.hdu.edu.cn/showproblem.php?pid=5072 单色三角形模型 现场赛和队友想了3个小时,最后发现想跑偏了。感觉好可惜的一道题,要...
  • u013081425
  • u013081425
  • 2014年10月27日 16:48
  • 1591

容斥原理专题一

抱歉,很久没有更新博客了。这几天集中刷了容斥原理的题目,于是就来写博客巩固下。容斥原理,我想大家在高中都或多或少的学过。虽然知道原理内容,但是用来解题的话,还是有点小障碍的,特别是不知道怎么写代码。如...
  • shengtao96
  • shengtao96
  • 2016年09月08日 21:33
  • 1181

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

题目大意:给你n个数,让你选出三个数,使得[(a, b) = (b, c) = (a, c) = 1] or [(a, b) ≠ 1 and (a, c) ≠ 1 and (b, c) ≠ 1]成立,...
  • xu12110501127
  • xu12110501127
  • 2015年01月16日 09:35
  • 630

HDU 5072 Coprime(数论+容斥原理)

Description 给出n(3≤n≤10^5)个数字,每个数ai满足1≤ai≤10^5,求有多少对(a,b,c)满足[(a,b)=(b,c)=(a,c)=1] or [(a,b)≠1and(a,...
  • V5ZSQ
  • V5ZSQ
  • 2016年08月03日 12:29
  • 177

hdu 5072 Coprime 约数,容斥原理

给出一些数,挑选其中3个,求两两互质和两两不互质的方案数。 需要对唯一分解原理有一定的理解,两个数不互质无非就是质因数分解后有相同的部分,比如a质因数分解为p1*p2*p3*p4...(指数省略),...
  • u013044116
  • u013044116
  • 2015年09月25日 12:27
  • 287
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:HDU 5072 Coprime (单色三角形+容斥原理)
举报原因:
原因补充:

(最多只允许输入30个字)