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
 

题目原形是同色三角形, 引用:就是求同色三角形的个数。总的三角形的个数是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 = ; int p[N][], vis[N], a[N], num[N];
int n;
void Prime()
{
memset(vis, , sizeof vis);
for(int i = ; i < N; ++i) p[i][] = ;
for(int i = ; i < N; ++i) if(!vis[i]) {
p[i][ ++p[i][] ] = i;
for(int j = i + i; j < N; j += i) {
vis[j] = ;
p[j][ ++p[j][] ] = i;
}
}
p[][ ++p[][] ] = ; //考虑0的情况
} void init()
{
memset(num, , sizeof num);
for(int k = ; k < n; ++k)
{
int now = a[k];
int cnt = p[ now ][];
for(int i = ; i < ( << cnt); ++i)
{
int t = ;
for(int j = ; j < cnt; ++j) if(( << j) & i) {
t *= p[ now ][j + ];
}
num[t]++;
}
}
} void solve()
{
ll ans = , res, sum = ;
ans = (ll)n * (n - ) * (n - ) / ; //类型转换一下,避免爆掉
int tot = ;
for(int k = ; k < n; ++k)
{
int now = a[k];
int cnt = p[now][];
res = ;
for(int i = ; i < ( << cnt); ++i)
{
int t = , g = ;
for(int j = ; j < cnt; ++j) if(( << j) & i) {
t *= p[ now ][j + ];
g++;
}
if(g & ) res += num[t];
else res -= num[t];
} if(res == ) continue;
sum += (res - ) * (n - res);
}
printf("%lld\n", ans - sum / ); }
int main()
{
// freopen("in", "r", stdin);
int _;
scanf("%d", &_);
Prime();
while(_ --)
{
scanf("%d", &n);
for(int i = ; i < n; ++i) scanf("%d", &a[i]);
init();
solve();
}
}

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

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

    题目链接:Coprime pid=5072"> 题面: Coprime Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: ...

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

    Description There are n people standing in a line. Each of them has a unique id number. Now the Ragn ...

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

    pid=5072">http://acm.hdu.edu.cn/showproblem.php?pid=5072 单色三角形模型 现场赛和队友想了3个小时,最后发现想跑偏了.感觉好可惜 ...

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

    Co-prime 第一发容斥,感觉挺有意思的 →_→ [题目链接]Co-prime [题目类型]容斥 &题意: 求(a,b)区间内,与n互质的数的个数. \(a,b\leq 10^{15}\) ...

  5. hdu 5072 Coprime

    http://acm.hdu.edu.cn/showproblem.php?pid=5072 题意:给出 n 个互不相同的数,求满足以下条件的三元无序组的个数:要么两两互质要么两两不互质. 思路:根据 ...

  6. hdu 5072 Coprime (容斥)

    Problem Description There are n people standing in a line. Each of them has a unique id number. Now ...

  7. Hdu 5072 Coprime(容斥+同色三角形)

    原题链接 题意选出三个数,要求两两互质或是两两不互质.求有多少组这样的三个数. 分析 同色三角形n个点 每两个点连一条边(可以为红色或者黑色),求形成的三条边颜色相同的三角形的个数反面考虑这个问题,只 ...

  8. hdu 5072 计数+容斥原理

    /* 题意: 给出n个数(n<100000), 每个数都不大于100000,数字不会有重复.现在随意抽出3个,问三个彼此互质 或者 三个彼此不互质的数目有多少. 思路: 这道题反着想,就是三个数 ...

  9. HDU 5072 Coprime 同色三角形问题

    好吧,我承认就算当时再给我五个小时我也做不出来. 首先解释同色三角形问题: 给出n(n >= 3)个点,这些点中的一些被涂上了红色,剩下的被涂上了黑色.然后将这些点两两相连.于是每三个点都会组成 ...

随机推荐

  1. SQL TO LINQ(Linqer神器)

    此软件可以把SQL语句转换成LINQ语句 首先把Linqer下载到本地, 1.在VS中创建.dbml文件和.cs文件 打开VS,创建一个控制台项目即可,再添加一个dbml项目 2.添加连接数据库 3. ...

  2. .pdb文件的使用方法

    1.Demo1:用DLL_01生成my.dll.my.pdb.my.lib文件. 2.Demo2:在DLL_01_APP_02中使用DLL_01的dll. 步骤: 1.vs2008打开DLL_01_A ...

  3. hdu1722(gcd)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1722 题意:要使一块蛋糕既能均分给a个人,又能均分给b个人,问至少需要分成几块(不需要每块都一样大小) ...

  4. Linux 查看 删除进程

    这东西,时间久不用总容易忘....记下来! 1. 在 LINUX 命令平台输入 1-2 个字符后按 Tab 键会自动补全后面的部分(前提是要有这个东西,例如在装了 tomcat 的前提下, 输入 to ...

  5. android中一个解决办法

    E  Trace(732): error opening trace file: No such file or directory (2)android api 的版本和模拟器的版本不一致导致的

  6. C#学习笔记---协变和逆变

    http://www.cnblogs.com/alphafly/p/4048608.html 协变是指方法能从委托的返回类型派生的一个类型. 逆变之方法获取的参数可以是委托参数类型的基类.

  7. babyClock 1.0发布(Android2.2以上)

    [总体说明] babyClock是以天为单位,进行提醒的小工具:可以设置多个闹钟,每个闹钟又按照频率分为多个提醒:过期后自动设置到明天该时刻进行提醒. 一个闹钟包含时间区段.提醒频率:进入时间区段时, ...

  8. 10g 11g配置Logical Standby

    1.创建一个物理Standby数据库 详细见11g Physical Standby配置 2.Standby数据库取消managed  recovery ALTER DATABASE RECOVER ...

  9. [LeetCode] Ugly Number

    Ugly Number Total Accepted: 20760 Total Submissions: 63208 Difficulty: Easy Write a program to check ...

  10. subversion安装使用

    这里仅针对subversion进行说明,未完待续. 一.下载subversion并安装: a.subversion 要做svn服务器的必须装 b.Tortoisesvn 仅仅是访问svn服务器的客户端 ...