poj3904
题意:给出n(n<10000)个数,这些数<=10000,要求选出四个数字且他们的最大公约数为1的(注意:不需要两两互质),有多少种选法。
分析:
容斥原理
假设平面上有一些圆,互相之间有重叠部分,我们要求这些圆覆盖的总面积(重叠部分只记一次)。计算方法就是:加上所有被覆盖了至少1次的面积加,减去所有被覆盖了至少2次的面积,加上所有被覆盖了至少3次的面积……对于奇数的就加,对于偶数的就减,最终结果即为覆盖的总面积。把这些圆变成是集合的话,那么这个计算过程就是容斥原理。
本题可以先计算n个数字选四个总共有多少种选法,然后减去公约数不是1的。把共同具有某一素因子的数字划分到同一个集合,属于统一集合的四个数最大公约数一定大于1,如果四个数字不同时属于任何集合则最大公约数一定为1。用总的组合数减去那些四个数字同时被同一个集合包括了的组合数,所得结果即为最终答案。但是这些一个四个数字的组合可能同时属于若干个集合,因此需要在这些集合之间进行容斥原理,以求每个需要被减去的四个数字的组合都恰好被减掉一次。
有一个统计数组,统计每个部分(集合或者集合的交集)中包含多少个数字(实际应该统计四个数字组合数,但是由于组合数可以通过数字数求得,在此为了方便只统计数字数)。实际操作时可以对每个数字分解质因数,把这些质因数在统计数组中的对应位加1。同时也要计算那些集合的重叠部分,也就是同时包含若干个质因子的情况,所以把每个数字质因子的所有组合方式相乘得到的数在统计数组中的对应位加1。还要记录它包含了几个质因子(是几个集合相交的交集)。以便以后容斥原理观察奇偶性时使用。
现在我们知道了所有部分包含的数字数量,但是计算的时候注意,我们求的不是数字数量,而是四个数字组合的数量。所以容斥原理加减过程加减的是四个数字的组合数。
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std; #define MAX_N 100005
#define MAX_FACTOR 16 int n, f[MAX_N];
int count[MAX_N];
int factor[MAX_FACTOR];
int prime_fac_num[MAX_N]; void input()
{
for (int i = ; i < n; i++)
scanf("%d", &f[i]);
} void make(int a)
{
int factor_cnt = ;
for (int i = ; i * i <= a; i++)
if (a % i == )
{
factor[factor_cnt++] = i;
while (a % i == )
a /= i;
}
if (a > )
factor[factor_cnt++] = a;
for (int i = ; i < ( << factor_cnt); i++)
{
int used_fac = ;
int cur_fac = ;
for (int j = ; (i >> j) > ; j++)
{
if ((i >> j) & )
{
used_fac++;
cur_fac *= factor[j];
}
}
count[cur_fac]++;
prime_fac_num[cur_fac] = used_fac;
} } long long cal(long long a)
{
return a * (a - ) * (a - ) * (a - ) / ;
} int main()
{
while (scanf("%d", &n) != EOF)
{
input();
memset(count, , sizeof(count));
memset(prime_fac_num, , sizeof(prime_fac_num));
for (int i = ; i < n; i++)
make(f[i]);
long long ans = cal(n);
for (int i = ; i <= ; i++)
{
if (prime_fac_num[i] & )
ans -= cal(count[i]);
else
ans += cal(count[i]);
}
printf("%lld\n", ans);
}
return ;
}
poj3904的更多相关文章
- [poj3904]Sky Code_状态压缩_容斥原理
Sky Code poj-3904 题目大意:给你n个数,问能选出多少满足题意的组数. 注释:如果一个组数满足题意当且仅当这个组中有且只有4个数,且这4个数的最大公约数是1,$1\le n\le 10 ...
- 【POJ3904】【P1202】水晶密码
说是莫比乌斯反演,其实只是玩儿玩儿内个miu函数而已…… 原题: wty 打算攻击 applepi 的用来存放机密数据的水晶系统. applepi 早有察觉,于是布置了一个密码系统来防备 wty ...
- POJ3904 Sky Code
题意 Language:Default Sky Code Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 3980 Accepte ...
- poj3904 Sky Code —— 唯一分解定理 + 容斥原理 + 组合
题目链接:http://poj.org/problem?id=3904 Sky Code Time Limit: 1000MS Memory Limit: 65536K Total Submiss ...
- POJ3904 Sky Code【容斥原理】
题目链接: http://poj.org/problem?id=3904 题目大意: 给你N个整数.从这N个数中选择4个数,使得这四个数的公约数为1.求满足条件的 四元组个数. 解题思路: 四个数的公 ...
- Sky Code(poj3904)
Sky Code Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 2085 Accepted: 665 Descripti ...
- poj 3904(莫比乌斯反演)
POJ 3904 题意: 从n个数中选择4个数使他们的GCD = 1,求总共有多少种方法 Sample Input 4 2 3 4 5 4 2 4 6 8 7 2 3 4 5 7 6 8 Sample ...
- ACM学习大纲
1 推荐题库 •http://ace.delos.com/usaco/ 美国的OI 题库,如果是刚入门的新手,可以尝试先把它刷通,能够学到几乎全部的基础算法极其优化,全部的题解及标程还有题目翻译可以b ...
- ACM训练大纲
1. 算法总结及推荐题目 1.1 C++ STL • STL容器: set, map, vector, priority_queue, queue, stack, deque, bitset• STL ...
随机推荐
- 反射工具类——ReflectUtils
测试方法:根据已知的方法名,来反射调用方法 package com.redmoon.forum.job; import java.util.ArrayList; import java.util.Li ...
- Java-TreeSet
如下: package 集合类.Set类; /** * Set不允许重复数据 */ /** * TreeSet 是用来进行集合排序的,请注意他和LinkedHashSet的区别. TreeSet是按照 ...
- Java基础-代理
我们书写执行一个功能的函数时,经常需要在其中写入与功能不是直接相关但很有必要的代 码,如日志记录,信息发送,安全和事务支持等,这些枝节性代码虽然是必要的,但它会带 来以下麻烦: 枝节性代码游离在功能性 ...
- SourceTree&Git部分名词解释
SourceTree&Git部分名词解释 克隆(clone):从远程仓库URL加载创建一个与远程仓库一样的本地仓库 提交(commit):将暂存文件上传到本地仓库(我们在Finder中对本地仓 ...
- 【bzoj3289】 Mato的文件管理
http://www.lydsy.com/JudgeOnline/problem.php?id=3289 (题目链接) 题意 求区间逆序对 Solution 离线无修改查询,莫队转移:树状数组维护区间 ...
- 洛谷P2925 [USACO08DEC]干草出售Hay For Sale
题目描述 Farmer John suffered a terrible loss when giant Australian cockroaches ate the entirety of his ...
- [NOIP2011] 提高组 洛谷P1311 选择客栈
题目描述 丽江河边有n 家很有特色的客栈,客栈按照其位置顺序从 1 到n 编号.每家客栈都按照某一种色调进行装饰(总共 k 种,用整数 0 ~ k-1 表示),且每家客栈都设有一家咖啡店,每家咖啡店均 ...
- C#获取局域网中的所有正在使用的IP地址
方法不是很好. using System; using System.Collections.Generic; using System.Linq; using System.Text; using ...
- java连接mysql(二)
模拟转账成功时的业务场景 import java.sql.*; public class TransactionDemo1 { public static void main(String[] arg ...
- groovy-语句
groovy语句类似于java语句,但是在groovy中的分号”;”是可选的.比如: 1 def x = [1, 2, 3] 2 println x 3 def y = 5; def x = y + ...