Codeforces 483B - Friends and Presents - [二分]

题目链接:https://codeforc.es/problemset/problem/483/B

You have two friends. You want to present each of them several positive integers. You want to present $cnt_1$ numbers to the first friend and $cnt_2$ 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 $cnt_1, cnt_2, x, y (1 \le cnt1, cnt2 < 10^9; cnt1 + cnt2 \le 10^9; 2 \le x < y \le 3·10^4)$ — the numbers that are described in the statement. It is guaranteed that numbers $x, y$ are prime.

Output
Print a single integer — the answer to the problem.

Examples
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 1, 3, 5 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.

题意:

现在要给两个人赠送一些正整数,要给第一个人送 $cnt_1$ 个正整数,要给第二个人送 $cnt_2$ 个正整数,且第一个人不想要能被 $x$ 整除的数,第二个人不想要能被 $y$ 整除的数。

现在你要求出最小的正整数 $v$,意味着你送出的正整数全部属于 $1 \sim v$。

题解:

二分倒是不难想到,就是算怎么给两人整数不太好想。

举个栗子:假设我现在 $v=7,x=2,y=3,cnt_1=3,cnt_2=3$,显然此时能给第一个人的数字有 $1,3,5,7$,能给第二个人的数字有 $1,2,4,5,7$;

那么我们知道,为了尽量使得 $v$ 小,我们应该尽量把第二个人不要的数字塞给第一个人,比如第二个人是不要 $3$ 的,但第一个人要,所以可以塞给他;同理,第一个人不要 $2,4$,但是第二个人要,可以塞给他;

假设 $1 \sim v$ 中能被 $x$ 整除的数有 $cnt_x$ 个,能被 $y$ 整除的数有 $cnt_y$ 个,能被 $xy$ 整除的数有 $cnt_xy$ 个;因此,第二个人不要而第一个人要的数字,其数量为 $cnt_y - cnt_xy$,第一个人不要而第二个人要的数字,其数量为 $cnt_x - cnt_xy$;

那么剩下来再要送出去的数字,就既不能被 $x$ 整除,也不能被 $y$ 整除了,如果这些数够分,那么 $v$ 就是可行的,不够分的话 $v$ 就不可行。

AC代码:

#include<bits/stdc++.h>
using namespace std;
int cnt1,cnt2,x,y;

int judge(int v)
{
    int cnt_x=v/x, cnt_y=v/y, cnt_xy=v/(x*y);
    int rest1=max(cnt1-(cnt_y-cnt_xy),0);
    int rest2=max(cnt2-(cnt_x-cnt_xy),0);
    return rest1+rest2<=v-cnt_x-cnt_y+cnt_xy;
}

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);

    cin>>cnt1>>cnt2>>x>>y;
    int l=1, r=2*(cnt1+cnt2);
    while(l<r)
    {
        int mid=l+(r-l)/2;
        if(judge(mid)) r=mid;
        else l=mid+1;
    }
    cout<<l<<'\n';
}

猜你喜欢

转载自www.cnblogs.com/dilthey/p/9951690.html