您的位置:首页 > 其它

[Codeforces #275 (Div. 2)B. Friends and Presents] 二分

2016-09-07 22:21 459 查看

[Codeforces #275 (Div. 2)B. Friends and Presents] 二分

题目链接[Codeforces #275 (Div. 2)B. Friends and Presents]

题意描述:从1,2,…,v中选择若干个数组成两个集合A,B。满足|A|=cnt1, |B|=cnt2,并且集合A中不含x的倍数,集合B中不含y的倍数。求最小的v。

解题思路:很明显的单调性,直接对v进行二分就好了。

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

typedef __int64 LL;

const LL INF = (1LL << 60);

LL N, M, X, Y;
LL v;
LL gcd(LL a, LL b) {
while(b ^= a ^= b ^= a %= b);
return a;
}
LL lcm(LL a, LL b) {
return a / gcd(a, b) * b;
}
bool check(LL k) {
LL a, b, c, temp;
LL A = N, B = M;
temp = k / lcm(X, Y);
a = k / X - temp;
b = k / Y - temp;
k -= temp;
c = k - a - b;
if(k < N + M) return false;
if(Y % X) {
A = max(0LL, A - b);
B = max(0LL, B - a);
if(B + A > c) return false;
} else {
B = max(0LL, B - a);
if(B + A > c) return false;
}
return true;
}
int main() {
//    freopen("input.txt", "r", stdin);
while(~scanf("%I64d %I64d %I64d %I64d", &N, &M, &X, &Y)) {
LL low = N + M, high = INF, mid;
while (high >= low) {
mid = (high + low) >> 1LL;
if(check(mid)) {
high = mid - 1;
} else {
low = mid + 1;
}
}
printf("%I64d\n", low);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: