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 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(n,3),只需减去不同色的三角形即可。对于每个点(数),与它互质的连红边,不互质的连蓝边,那么对于该点不同色三角形个数为蓝边数*红边数/2,因为同一个三角形被计算了两次。那么同色三角形个数为C(n,3) - ∑蓝边数*红边数/2。

问题是:如何求 原来序列里面的n个数跟某个数k不互质的个数(互质的就是n-k了)?

可以将原来的n个数,每一个都把他们的不同的质因数都求出来,然后枚举它们能够组合的数(1 << cnt),用一个数组num记录,每枚举到一个数,那么数组对应的就+1

对于数k,也把它的不同质因数求出来,同样枚举它能够组合的所有数t,然后奇加偶减num

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <queue>
#include <map>
using namespace std;
typedef long long ll;
const int N = 200005;

int p[N][15], vis[N], a[N], num[N];
int n;
void Prime()
{
    memset(vis, 0, sizeof vis);
    for(int i = 0; i < N; ++i) p[i][0] = 0;
    for(int i = 2; i < N; ++i) if(!vis[i]) {
        p[i][ ++p[i][0] ] = i;
        for(int j = i + i; j < N; j += i) {
            vis[j] = 1;
            p[j][ ++p[j][0] ] = i;
        }
    }
    p[0][ ++p[0][0] ] = 1;    //考虑0的情况
}

void init()
{
    memset(num, 0, sizeof num);
    for(int k = 0; k < n; ++k)
    {
        int now = a[k];
        int cnt = p[ now ][0];
        for(int i = 1; i < (1 << cnt); ++i)
        {
            int t = 1;
            for(int j = 0; j < cnt; ++j) if((1 << j) & i) {
                t *= p[ now ][j + 1];
            }
            num[t]++;
        }
    }
}

void solve()
{
    ll ans = 0, res, sum = 0;
    ans = (ll)n * (n - 1) * (n - 2) / 6;    //类型转换一下,避免爆掉
    int tot = 0;
    for(int k = 0; k < n; ++k)
    {
        int now = a[k];
        int cnt = p[now][0];
        res = 0;
        for(int i = 1; i < (1 << cnt); ++i)
        {
            int t = 1, g = 0;
            for(int j = 0; j < cnt; ++j) if((1 << j) & i) {
                t *= p[ now ][j + 1];
                g++;
            }
            if(g & 1)  res += num[t];
            else       res -= num[t];
        }

        if(res == 0) continue;
        sum += (res - 1) * (n - res);
    }
    printf("%lld\n", ans  - sum / 2);

}
int main()
{
   // freopen("in", "r", stdin);
    int _;
    scanf("%d", &_);
    Prime();
    while(_ --)
    {
        scanf("%d", &n);
        for(int i = 0; i < n; ++i) scanf("%d", &a[i]);
        init();
        solve();
    }
}

时间: 2024-10-12 12:34:38

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

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

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

[容斥原理] 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 (莫比乌斯反演+容斥+同色三角形)

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

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

HDU - 4135 Co-prime(容斥原理)

Question 参考 题意找出[a,b]中与n互质的数的个数分析通常我们求1-n中与n互质的数的个数都是用欧拉函数.但如果n比较大或者是求1-m中与n互质的数的个数等等问题,要想时间效率高的话还是用容斥原理.先对n分解质因数,分别记录每个质因数, 那么所求区间内与某个质因数不互质的个数就是 m/r(i),假设r(i)是r的某个质因子 假设只有三个质因子, 总的不互质的个数应该为p1+p2+p3-p1*p2-p1*p3-p2*p3+p1*p2*p3. pi代表m/r(i),即与某个质因子不互质的