Codeforces Round #275 (Div. 2) --B Friends and Presents

题目链接:Friends and Presents



Friends and Presents
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

You have two friends. You want to present each of them several positive integers. You want to present cnt1 numbers to the first friend andcnt2 numbers to the second friend. Moreover, you want all presented numbers to be distinct, that also means that no number should be presented to both friends.

In addition, the first friend does not like the numbers that are divisible without remainder by prime number x. The second one does not like the numbers that are divisible without remainder by prime number y. Of course, you're not going to present your friends numbers they don't like.

Your task is to find such minimum number v, that you can form presents using numbers from a set 1, 2, ..., v. Of course you may choose not to present some numbers at all.

A positive integer number greater than 1 is called prime if it has no positive divisors other than 1 and itself.

Input

The only line contains four positive integers cnt1cnt2xy (1 ≤ cnt1, cnt2 < 109cnt1 + cnt2 ≤ 1092 ≤ x < y ≤ 3·104) — the numbers that are described in the statement. It is guaranteed that numbers xy are prime.

Output

Print a single integer — the answer to the problem.

Sample test(s)
input
3 1 2 3
output
5
input
1 3 2 3
output
4
Note

In the first sample you give the set of numbers {1, 3, 5} to the first friend and the set of numbers {2} to the second friend. Note that if you give set {1, 3, 5} to the first friend, then we cannot give any of the numbers 135 to the second friend.

In the second sample you give the set of numbers {3} to the first friend, and the set of numbers {1, 2, 4} to the second friend. Thus, the answer to the problem is 4.





大致题意:A有两个朋友B和C,B和C都很喜欢数字,现在A要送给他们各自一些不同的数字来做礼物,但是B不喜欢素数x,所以不能送给他x的倍数;同样如此,C不喜欢素数y,也不能送给他y的倍数。现在的任务是从找到一个最小的数v,使得从1~v里面可以满足A的要求,分别送给B和C。



解题思路:最开始写的时候,用的是暴力枚举,但是结果老是在一个样例上错,可能我的想法不对吧,得不到正确答案。后来看给出的官方解法是用二分。。。想了半天,也没想太明白,关键是想不好怎么用二分呀,该对谁二分,写了这题,又涨姿势了,原来可以从1到无穷大二分,感觉好神奇呀。二分,就要找好二分区间时的条件,根据题目要求,又想了想,才艰难的把这题给搞了。。。


具体解法思路:主要是二分的解决思想不好想,其实仔细想想,也差不多,因为不知道最小的满足要求的数,所以在1~1000000000之间二分,查找满足要求的最小数。中间划分区间的条件是:n <= (mid - mid/x)中的mid/x是1~mid之间的x的倍数的个数,那么mid - mid/x就是1~mid之中可以给第一个朋友的数,这个条件就是当mid可以满足第一个朋友要求的时候;同理,  m <= (mid - mid/y)就代表mid可以满足第二个朋友要求的时候;但是这时候可能1~mid中间有数既满足第一个朋友的要求,又满足第二个朋友的要求,那样就可能刚才计算的时候,这些数被重复使用了,但在实际情况中,是不够分的,所以,我们用 n+m <= mid - mid/(x*y)判断,mid满足两者要求的数之和足够分,这样就说明,这个mid是满足情况的,就不是最小的,我们就要取左边的区间,继续寻找更小的满足条件的mid,直到不满足条件即可。





AC代码:

#include <cstdio>
#include <algorithm>
using namespace std;

int main(){
//	freopen("in.txt", "r", stdin);
	int n, m, x, y;
	while(scanf("%d%d%d%d", &n, &m, &x, &y) == 4){
		int l = 1, r = 2e9;         //枚举区间端点
		while(l < r){               //二分
			int mid = l + (r - l)/2;
			if( n <= (mid - mid/x)  &&  m <= (mid - mid/y) && n+m <= mid - mid/(x*y))   //划分区间的条件
				r = mid;
			else
			  	l = mid + 1;
		}
		printf("%d\n", r);	
	}
	return 0;
}





  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值