hdu 5072 Coprime(同色三角形+容斥)
http://acm.hdu.edu.cn/showproblem.php?pid=5072
单色三角形模型
现场赛和队友想了3个小时,最后发现想跑偏了。感觉好可惜的一道题,要是知道这个模型....就可以轻松的拿银了啊。。。
题意不再赘述,就是求同色三角形的个数。总的三角形的个数是C(n,3),只需减去不同色的三角形即可。对于每个点(数),与它互质的连红边,不互质的连蓝边,那么对于该点不同色三角形个数为蓝边数*红边数/2,因为同一个三角形被计算了两次。那么同色三角形个数为C(n,3) - ∑蓝边数*红边数/2。
我们只需求出蓝边数就能得知红边数,怎么求与该数不互质的数的个数?首先对原来的数质因子分解,把这些质因子的所有组合枚举出来,每个质因子最多使用一次,得到若干个质因子的组合为ansNum,使用容斥原理,观察ansNum的质因子的个数,若是奇数就加上所有能被ansNum整数的数的个数,否则就减去。这样求出蓝边数,红边数也就已知了。
#include <stdio.h>
#include <iostream>
#include <map>
#include <set>
#include <bitset>
#include <list>
#include <stack>
#include <vector>
#include <math.h>
#include <string.h>
#include <queue>
#include <string>
#include <stdlib.h>
#include <algorithm>
#define LL __int64
//#define LL long long
#define eps 1e-9
#define PI acos(-1.0)
using namespace std;
const LL INF = 1<<30;
const int maxn = 100010;int test;
LL n;
int a[maxn],num[maxn];
int prime[maxn];
bool flag[maxn];
int fact[maxn][20];
int coun[maxn];void getPrime()
{memset(flag,0,sizeof(flag));flag[1] = true;prime[0] = 0;for(int i = 2; i < maxn; i++){if(flag[i] == false)prime[++prime[0]] = i;for(int j = 1; j <= prime[0]&&i*prime[j] < maxn; j++){flag[prime[j]*i] = true;if(i%prime[j] == 0)break;}}
}void getFact(int dig, int pos)
{int tmp = dig;for(int i = 1; i <= prime[0] && prime[i]*prime[i] <= tmp; i++){if(tmp % prime[i] == 0){fact[pos][coun[pos]++] = prime[i];while(tmp % prime[i] == 0)tmp /= prime[i];}if(tmp == 1)break;}if(tmp > 1)fact[pos][coun[pos]++] = tmp;
}void init()
{for(int i = 2; i <= 100000; i++){for(int j = i+i; j <= 100000; j += i)num[i] += num[j];}
}int main()
{getPrime();scanf("%d",&test);while(test--){memset(num,0,sizeof(num));scanf("%I64d",&n);for(int i = 1; i <= n; i++){scanf("%d",&a[i]);num[a[i]]++;}init();memset(coun,0,sizeof(coun));LL ans = 0;for(int i = 1; i <= n; i++){LL res = 0;getFact(a[i], i);for(int j = 1; j < (1<<coun[i]); j++){LL ansNum = 1;int cnt = 0;for(int k = 0; k < coun[i]; k++){if(j & (1<<k) ){ansNum *= fact[i][k];cnt++;}}if(cnt & 1)res += (num[ansNum]-1);elseres -= (num[ansNum]-1);}ans += (n-1-res)*res;}ans = n*(n-1)*(n-2)/6 - ans/2; //注意n为LLprintf("%I64d\n",ans);}return 0;
}
hdu 5072 Coprime(同色三角形+容斥)相关推荐
- hdu 5072 Coprime
http://acm.hdu.edu.cn/showproblem.php?pid=5072 题意:给出 n 个互不相同的数,求满足以下条件的三元无序组的个数:要么两两互质要么两两不互质. 思路:根据 ...
- HDU 2841 Visible Trees(容斥)题解
题意:有一块(1,1)到(m,n)的地,从(0,0)看能看到几块(如果两块地到看的地方三点一线,后面的地都看不到). 思路:一开始是想不到容斥...后来发现被遮住的地都有一个特点,若(a,b)有gcd ...
- HDU 6143 Killer Names【容斥定理】【排列组合】
题目来戳呀 Problem Description Galen Marek, codenamed Starkiller, was a male Human apprentice of the Sith ...
- HDU 6143 Killer Names(容斥+组合)
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> ...
- HDU - 5468 Puzzled Elena (容斥/莫比乌斯)
做了好几个容斥了,一直找不到feel,这个做完在现在有一点感觉了.虽然刚开始也不会.但就是发现感觉不一样了. 首先,不考虑树的关系,单纯给出一个m,还有一个集合(里面数字任意),求集合里面跟m互质的数 ...
- 容斥 - HDU 4135 Co-prime
Co-prime Problem's Link: http://acm.hdu.edu.cn/showproblem.php?pid=4135 推荐: 容斥原理 Mean: 给你一个区间[l,r]和 ...
- hdu 50722014鞍山现场赛C题(容斥原理+同色三角形)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5072: 题意:找出一个3元集合使集合中的两两互质,或两两不互质.这样的集合的个数. 分析:将每个数都幻 ...
- HDU 6143 Killer Names(排列+容斥,dp)
Killer Names HDU 6143 (容斥+排列组合,dp+整数快速幂) 2017ACM暑期多校联合训练 - Team 8 1011 Killer Names 题目链接 Time Limit: ...
- Visible Trees HDU - 2841(容斥)
Visible Trees HDU - 2841 题意: 大概就是有个m*n个点的矩形从(1,1)到(m,n),问从(0,0)出发直线看过去最多能看到几个点. 题解: 容斥做法参考 这个题和AcWin ...
最新文章
- java异常及日志注意事项
- Python实现进度条总结
- 关于删除数据仓库的数据
- 一个简单的从windows系统往AWS上直接拷贝文件的脚本
- linux 进程开始与终止
- if函数 字体自动标红_发喜糖!REPT函数和图表订婚了~~
- win10隐藏linux,Win10如何隐藏Windows Defender任务栏图标
- 问题root@localhost's password:localhost:permission denied,please try again
- java数字类型_Java数据类型
- Building an FTP Test Plan
- android软件欢迎界面,Android应用中实现一个软件启动的欢迎界面
- c java交互,Java与C交互
- silverlight如何通过单独部署的WCF站点访问sharepoint2013的图片库
- mysql with 查询_mysql笔记(6)-多表查询之with
- 服务器各项指标的图形化显示
- matlab 安装教程:matlab 2016a(matlab R2016a)
- 《GPU编程与CG语言之阳春白雪下里巴人》阅读笔记 第一章+第二章
- 基于winform的打印标签模板设计器以及打印辅助类
- [Android系统开发]Launcher Hotseat图标居中排列
- 方正高拍仪文件上传到服务器,高拍仪拍摄文件后如何进行文字识别?本地文件能否导入高拍仪进行识别?...