hdu--5072--容斥原理

tmd还是自己没做出拿牌题。。。

可以看下别人的博客 有很详细的解释

但我自己开始没想出来 cao......

其实 这个思路不算特别难的 和我这几天遇到的dp题相比

注意下 hash[ i ]表示给定的n个数中是 i 的倍数的数有几个

要注意下 n * (n-1) * (n-2 ) / 6会超Int整数上限 我TMD的就在那边折腾了半小时 ...

  1 #include <iostream>
  2 #include <cstring>
  3 #include <vector>
  4 using namespace std;
  5
  6 typedef __int64 LL;
  7 int num;
  8 LL n;
  9 const int size = 100000;
 10 int a[size+10];
 11 bool flag[size+10];
 12 bool vis[size+10];
 13 int prime[size+10];
 14 int hash[size+10];
 15 vector<int>ve[size+10];
 16
 17 void init( )
 18 {
 19     num = 0;
 20     memset( vis , true , sizeof(vis) );
 21     vis[0] = vis[1] = false;
 22     for( int i = 2 ; i<=size ; i++ )
 23     {
 24         if( vis[i] )
 25         {
 26             prime[ num++ ] = i;
 27             int j = i * 2;
 28             while( j<=size )
 29             {
 30                 vis[j] = false;
 31                 j += i;
 32             }
 33         }
 34     }
 35 }
 36
 37 void fenjie( int y , int x )
 38 {
 39     ve[y].clear( );
 40     for( int i = 0 ; i<num&&prime[i]*prime[i]<=x ; i++ )
 41     {
 42         if( x%prime[i]==0 )
 43         {
 44             ve[y].push_back( prime[i] );
 45             while( x%prime[i]==0 )
 46             {
 47                 x /= prime[i];
 48             }
 49         }
 50     }
 51     if( x>1 )
 52     {
 53         ve[y].push_back( x );//将x分解出来的话 会有多少个质因子
 54     }
 55 }
 56
 57 LL solve( )
 58 {
 59     for( int i = 2 ; i<=size ; i++ )
 60     {
 61         for( int j = i ; j<=size ; j+=i )
 62         {
 63                 if( flag[j] )
 64                     ++ hash[i];
 65         }
 66     }
 67     LL ans = 0;
 68     LL var , sum;
 69     int cnt , veSize;
 70     for( int i = 0 ; i<n ; i++ )
 71     {
 72         veSize = ve[i].size();
 73         sum = 0;
 74         for( int j = 1 ; j<( 1<<veSize ) ; j++ )
 75         {
 76             cnt = 0;
 77             var = 1;
 78             for( int k = 0 ; k<veSize ; k++ )
 79             {
 80                 if( j&(1<<k) )
 81                 {
 82                     ++ cnt;
 83                     var *= (LL) ve[i][k];
 84                 }
 85             }
 86             if( cnt&1 )//奇加偶减
 87             {
 88                 sum += hash[var];
 89             }
 90             else
 91             {
 92                 sum -= hash[var];
 93             }
 94         }
 95         if( sum==0 )// sum   与a[i]非 互质的个数
 96             continue;
 97         ans += (LL)( (sum-1) * ( n-sum ) );
 98     }
 99     return ans/2;
100 }
101
102 int main()
103 {
104     cin.sync_with_stdio(false);
105     init( );
106     int t;
107     LL ans;
108     cin >> t;
109     while( t-- )
110     {
111         memset( hash , 0 , sizeof(hash) );
112         memset( flag , false , sizeof(flag) );
113         cin >> n;
114         for( int i = 0 ; i<n ; i++ )
115         {
116             cin >> a[i];
117             flag[ a[i] ] = true;
118             fenjie( i , a[i] );
119         }
120         ans = solve( );
121         ans = (LL)( n*(n-1)*(n-2)/6 - ans );
122         cout << ans << endl;
123     }
124     return 0;
125 }

时间: 2024-10-07 11:10:25

hdu--5072--容斥原理的相关文章

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 1695 容斥原理或莫比乌斯反演

GCD Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 5310    Accepted Submission(s): 1907 Problem Description Given 5 integers: a, b, c, d, k, you're to find x in a...b, y in c...d that GCD(x, y)

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 计数+容斥原理

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

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 容斥原理

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为顶点的三角形

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,由于同一个三角形被计算了两次. 那么同