【codeforces 483B】Friends and Presents

【链接】 我是链接,点我呀:)
【题意】

【题解】


我们可以二分n的值,设为mid
那么对于n=mid
我们可以算出来以下3个东西
temp1 = n/x;
temp2 = n/y;
temp3 = n/lcm(x,y);//lc(x,y)表示x和y的最小公倍数
temp1是第一个人在1..n中不喜欢的数的个数
temp2是第二个人在1..n中不喜欢的数的个数
temp3是两个人在1..n中都不喜欢的数的个数。
那么我们把1..n中temp1-temp3个第一个人不喜欢的数字全给第二个人
然后把1..n中temp2-temp3个第二个人不喜欢的数字全给第一个人
这样就能最大化地利用所有数字了。
然后
cnt[1]-=temp2-temp3
cnt[2]-=temp1-temp3
然后如果cnt[1]<0,cnt[1] = 0;
如果cnt[2]<0,cnt[2]=0;
然后cnt[1]+cnt[2]就是两个人还需要的数字的个数了.
然后n个数字还剩下n-temp1-temp2+temp3个数字。
这些数字是他们都能接受的。
那么看看cnt[1]+cnt[2]是不是小于等于那些剩余的数字就好了。
如果ok
那么就说明n=mid是可行的。
按照是否可行更改l和r的值就ok

【代码】

#include <bits/stdc++.h>
#define LL long long
using namespace std;

const int N = 1e4;

LL cnt[3],x,y;

bool ok(LL v){
    LL temp1 = v/x;
    LL temp2 = v/y;
    LL temp3 = v/(x*(y/__gcd(x,y)));
    LL tc1 = cnt[1],tc2 = cnt[2];
    tc1-=(temp2-temp3);
    tc2-=(temp1-temp3);
    if (tc1<0) tc1 = 0;
    if (tc2<0) tc2 = 0;
    LL rest = v-temp1-temp2+temp3;
    if (tc1+tc2<=rest) return true;
    return false;
}

int main()
{
    //freopen("D:\\rush.txt","r",stdin);
    ios::sync_with_stdio(0),cin.tie(0);
    cin >> cnt[1] >> cnt[2] >> x >> y;
    LL l = 1,r = 1e10,temp = -1;
    while(l<=r){
        LL mid = (l+r)>>1;
        if (ok(mid)){
            temp = mid;
            r = mid - 1;
        }else l = mid + 1;
    }
    cout<<temp<<endl;
    return 0;
}

转载于:https://www.cnblogs.com/AWCXV/p/9742231.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值