[poj 3904] sky code 解题报告(组合计算+容斥原理)
题目链接:http://poj.org/problem?id=3904
题目大意:
给出一个数列,询问从中取4个元素满足最大公约数为1的方案数
题解:
很显然,ans=总的方案数-最大公约数大于1的4个元素的组合的方案数
=总的方案数-存在公约数大于1的4个元素的组合的方案数
考虑后者如何计算
容斥一下
后者=含有一个质因子(不仅仅是一个,应该是至少一个,后面的同理)的元素的个数取4的方案数-含有两个质因子的元素的个数取4的方案数+含有三个质因子的元素的个数取4的方案数...
朴素做法是枚举质因子,判断当前的质因子的公倍数有几个然后统计答案,但是我们还有其他的方法
怎么做呢?我们是不是可以枚举约数,根据这个约数由几个不同的质因子组成判断是+号还是-号(质因子不可以重复),并且在已知下它的倍数在数列中出现的次数计算对答案的贡献
具体实现就是对于数列中的每一个元素处理它的不同质因子组合成的约数,注意这些约数的质因子不可以重复。这样的话,当我们枚举到这个约数的时候,我们就可以直接知道上述的两个信息
一个小理解:注意一个数可能在一个质因子的时候产生贡献,同时也在多个质因子的时候同样产生贡献
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<vector>
using namespace std;
typedef long long ll; const int N=1e4+;
int n;
int a[N],num[N],cunt[N];
vector <int> pr;
void div(int x)
{
pr.clear();
for (int i=;i*i<=x;i++)
{
if (x%i) continue;
pr.push_back(i);
while (x%i==) x/=i;
}
if (x>) pr.push_back(x);
}
void solve(int x)
{
div(x);
int size=pr.size();
int all=(<<size);
for(int i=;i<all; i++)
{
ll t=,ci=;
for(int j=;j<size;j++)
{
if(i&(<<j))
{
t*=pr[j];
ci++;
}
}
cunt[t]++;//该不含重复质因子的约数的倍数出现的次数
num[t]=ci;//记录下含有几个不同的质因子
}
}
ll C(ll x)
{
return x*(x-)*(x-)*(x-)/;
}
int main()
{
while (cin>>n)
{
memset(cunt,,sizeof(cunt));
for (int i=;i<=n;i++) scanf("%d",a+i),solve(a[i]);
ll res=;
for (int i=;i<=;i++)
if (cunt[i])
{
if (num[i]&) res+=C(cunt[i]);
else res-=C(cunt[i]);
}
res=C(n)-res;
printf("%lld\n",res);
}
return ;
}
[poj 3904] sky code 解题报告(组合计算+容斥原理)的更多相关文章
- POJ 3904 Sky Code (容斥原理)
B - Sky Code Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Submit ...
- POJ 3904 Sky Code
题意:给定n个数ai, ai <= 10000, n <= 10000, 从中选出4个数要求gcd为1,这样的集合有多少个? 分析:首先总共集合nCr(n, 4) = n*(n-1)*(n ...
- [poj 2773] Happy 2006 解题报告 (二分答案+容斥原理)
题目链接:http://poj.org/problem?id=2773 题目大意: 给出两个数m,k,要求求出从1开始与m互质的第k个数 题解: #include<algorithm> # ...
- Tarjan算法求解桥和边双连通分量(附POJ 3352 Road Construction解题报告)
http://blog.csdn.net/geniusluzh/article/details/6619575 在说Tarjan算法解决桥和边双连通分量问题之前我们先来回顾一下Tarjan算法是如何 ...
- POJ 3126 Prime Path 解题报告(BFS & 双向BFS)
题目大意:给定一个4位素数,一个目标4位素数.每次变换一位,保证变换后依然是素数,求变换到目标素数的最小步数. 解题报告:直接用最短路. 枚举1000-10000所有素数,如果素数A交换一位可以得到素 ...
- [POJ 1001] Exponentiation C++解题报告 JAVA解题报告
Exponentiation Time Limit: 500MS Memory Limit: 10000K Total Submissions: 126980 Accepted: 30 ...
- poj 3080 Blue Jeans 解题报告
题目链接:http://poj.org/problem?id=3080 该题属于字符串处理中的串模式匹配问题.题目要求我们:给出一个DNA碱基序列,输出最长的相同的碱基子序列.(保证在所有的序列中都有 ...
- 【原创】poj ----- 2376 Cleaning Shifts 解题报告
题目地址: http://poj.org/problem?id=2376 题目内容: Cleaning Shifts Time Limit: 1000MS Memory Limit: 65536K ...
- 【原创】poj ----- 1611 The Suspects 解题报告
题目地址: http://poj.org/problem?id=1611 题目内容: The Suspects Time Limit: 1000MS Memory Limit: 20000K To ...
随机推荐
- ORA-38760: This database instance failed to turn on flashback database
ORA-38760: This database instance failed to turn on flashback database 问题背景: 測试数据库运行shutdown ...
- 【动态树问题】LCT学习笔记
我居然还不会LCT QAQ真是太弱了 必须学LCT QAQ ------------------线割分是我www------------ LinkCut-Tree是基于Splay(由于Splay能够非 ...
- 跟我学设计模式视频教程——适配器模式,适配器模式VS装饰模式
课程视频 适配器模式 适配器模式VS装饰模式 唠嗑 课程笔记 课程笔记 课程代码 课程代码 新课程火热报名中 课程介绍
- Ubuntu 16.04 安装 Open Jdk
sudo add-apt-repository ppa:openjdk-r/ppa sudo apt-get update sudo apt-get install openjdk-7-jdk
- m_Orchestrate learning system---二、如何实现验证码自动点击刷新
m_Orchestrate learning system---二.如何实现验证码自动点击刷新 一.总结 一句话总结:传过去的url带随机数来避免读取缓存 onclick="this.src ...
- luogu 2308添加括号
添加括号 传送门 题目大意 现在要添上n-1对括号,加法运算依括号顺序进行,得到n-1个中间和,求出使中间和之和最小的添括号方法. 这道题其实是一个很简单的区间dp,中间和的意思是括号里面的和,也就是 ...
- Dos.ORM使用教程
Dos.C#.Net使用 Dos.ORM(原Hxj.Data)于2009年发布,并发布实体生成工具.在开发过程参考了多个ORM框架,特别是NBear,MySoft.EF.Dapper等.吸取了他们的一 ...
- PHP正则表达式函数总结
/* 测试环境:PHP5.3.29(PCRE8.32) */ 常用函数:(正则表达式规则基本同JS_RE_Read.txt) PS:1.PHP中的PCRE一般仅使用这三个修饰符:"i&quo ...
- Android TextView加上阴影效果
<TextView android:id="@+id/test_shadow" android:layout_width="wrap_content" a ...
- NEON基本知识
http://blog.csdn.net/EmSoftEn/article/details/51834171 http://blog.csdn.net/yxnyxnyxnyxnyxn/article/ ...