zoj 3233 容斥原理 + 双条件

题目来源:

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3490

题意:  给出两个集合Y , N , 给出区间【low , high】 , 问在 这个区间有多少个这样的数,x ,
 满足, 集合Y中至少一个数被x 整除, 且 集合 N中至少一个数不被x 整除。

分析:两个条件

Q1 :  集合Y中至少一个数被x 整除 , 满足这个条件的个数为 A;

Q2 :  集合 N中至少一个数不被x 整除。 满足这个条件的个数为B

集合 s = {1 ,2 ,....n} 中 满足 这两个条件的个数, 为 :
 A ∩ B = A - (A- B) = A - (A ∩
 ? B)

非B  表示,  满足 条件  集合N中 所有数被 x
 整除的
   , 这样 x 的个数。

所以在 计算 每个节点的个数时 , 使用 这个函数

LL cel(LL a, LL num){
return num / a - num / LCM(a , lcm)
;
}

代码如下:


using namespace std ;
const double EPS = 1e-16 ;
typedef long long LL ;
const int Max_N = 505;
const double inf = 1e10 ; // 这个 开小了 1e9 都WA了好几次
int n , m;
LL low , high , lcm , a[Max_N] , b ;
LL GCD(LL x, LL y){
return y == 0 ? x : GCD(y , x % y) ;
}
LL LCM(LL x, LL y){ // 处理巧妙,防止越界
LL g;
g = GCD(x , y) ;
if(x / g > high / y)
return high + 1 ;
return x / g * y ;
}
LL cel(LL a, LL num){
return num / a - num / LCM(a , lcm) ;
}
void dfs(int now , int Count , LL lcm_1 , LL &sum , LL num){
lcm_1 = LCM(a[now] , lcm_1) ;
if(Count & 1)
sum += cel(lcm_1 , num);
else sum -= cel(lcm_1 , num);
for(int i = now + 1 ; i < n ; i++){
dfs(i , Count +1 , lcm_1 , sum , num ) ;
}
}
void ok(){
LL sum1 = 0 ,sum2 = 0;
int i;
for(i = 0 ; i < n ;i++){
dfs(i, 1 , a[i] , sum1 , high) ;
}
for(i = 0 ; i < n ;i++){
dfs(i, 1 , a[i] , sum2 , low -1) ;
}
printf("%lld\n" , sum1 - sum2) ;
}
int main(){
int i ;
while(cin>>n >> m >> low >> high){
lcm = 1 ;
if(n == 0 && m ==0 && low == 0 && high == 0) break ;
for(i = 0 ; i < n ; i++)
scanf("%lld" , &a[i]) ;
for(i = 0 ; i < m ; i++){
scanf("%lld" , &b) ;
lcm = LCM(lcm , b) ;
}
ok() ;
}
}

时间: 2024-10-10 16:25:10

zoj 3233 容斥原理 + 双条件的相关文章

ZOJ 3233 Lucky Number --容斥原理

这题被出题人给活活坑了,题目居然理解错了..哎,不想多说. 题意:给两组数,A组为幸运基数,B组为不幸运的基数,问在[low,high]区间内有多少个数:至少被A组中一个数整除,并且不被B中任意一个数整除.|A|<=15. 分析:看到A长度这么小,以及求区间内满足条件的个数问题,容易想到容斥原理,因为不被B中任意一个数整除,所以将B数组所有数取一个最小公倍数LCM,那么就变成了幸运数字都不会被这个LCM整除. 然后枚举子集,实现要将A中元素去除相互整除的情况,比如A = [2,4],这时因为被至

ZOJ 3233 Lucky Number

Lucky Number Time Limit: 5000ms Memory Limit: 32768KB This problem will be judged on ZJU. Original ID: 323364-bit integer IO format: %lld      Java class name: Main Watashi loves M mm very much. One day, M mm gives Watashi a chance to choose a number

ZOJ 3868(容斥原理+快速幂)

GCD Expectation Time Limit: 4 Seconds      Memory Limit: 262144 KB Edward has a set of n integers {a1, a2,...,an}. He randomly picks a nonempty subset {x1, x2,-,xm} (each nonempty subset has equal probability to be picked), and would like to know the

python-联系-双条件-if-else

age=float(raw_input("enter your age:"))    grade=int(raw_input("enter your grade:"))     if age >=8:         if grade >=3:             print "you can play this game."     else:          print "sorry ,you can't play

ZOJ 3233 Lucky Number 容斥

给你a数组和b数组 求x到y之间有多少个数至少被a中一个数整除并且至少不被b中一个数整除 容斥第一问很简单 第二问可以考虑反面 设满足被a中至少一个数整除的数有sum1个 在被a中至少一个数整除的前提下 被b中所有数整除的数有sum2 答案就是sum1-sum2 在dfs的时候溢出了 借鉴了某大牛的方法 #include <cstdio> #include <cstring> using namespace std; typedef long long LL; const int

[CFgym101061C]Ramzi(贪心,双条件最短路)

题目链接:http://codeforces.com/gym/101061/problem/C 题意:一张图,图上的边有两种,一种是车道,一种是人行道.一个人要从A点到B点,可以坐车也可以走人行道.这个人希望在走最少的路的情况下尽可能早地到达B点(保证走路最少的清空下坐车时间最少),问要走多少路,一共花费多久. pair<int, int>保存这个人需要走路的时间和共计的时间,读入更新图的时候需要判断仔细.利用pair自身比较运算符优先判断first元素可以直接跑floyd. 1 /* 2 ━

Excel各种条件求和的公式汇总

经常和Execl打交道的人肯定觉得求和公式是大家时常用到的.Excel里有哪几路求和公式呢?他们的使用方式又是怎样?我为大家汇总一下. 使用SUMIF()公式的单条件求和: 如要统计C列中的数据,要求统计条件是B列中数据为"条件一".并将结果放在C6单元格中,我们只要在C6单元格中输入公式“=SUMIF(B2:B5,"条件一",C2:C5)”即完成这一统计.   SUM()函数+IF()函数嵌套的方式双条件求和: 如统计生产一班生产的质量为“合格”产品的总数,并将结

那些年我们一起挖掘SQL注入 - 6.全局防护Bypass之一些函数的错误使用

0x01 背景 PHP程序员在开发过程中难免会使用一些字符替换函数(str_replace).反转义函数(stripslashes),但这些函数使用位置不当就会绕过全局的防护造成SQL注入漏洞. 0x02 漏洞分析 str_replace函数的错误使用 第一种情况是写程序时会使用str_replace函数将参数中的单引号.括号等字符替换为空,这样在一些双条件查询的情况就会引发注入问题.缺陷代码如下: <?phprequire_once('common.php');$conn = mysql_co

awk命令笔记

awk是一种可以处理数据.产生格式化报表的语言,功能相当强大.awk的工作方式是读取数据文件,将每一行数据视为一条记录(record),每笔记录以字段分隔符分成若干字段,然后输出各个字段的值.awk对每一条记录,都会套用一个"样式{操作}",如果该行符合样式,就执行指定的操作.样式或操作之一,可以省略.如果只有样式,表示要显示符合样式的数据行:如果只有操作,表示对每一数据行都执行该项操作. 以下是awk常用的作用格式: awk"样式"文件:把符合样式的数据行显示出来