逗比了,比赛的时候想破脑袋都没想到怎么做
赛后看标签说是二分,很轻松的就A掉了...
二分大法真心好
二分的难点就在于我们对于当前的一个数字,判断它是否满足条件
对于当前这个数,设为ans
则ans范围内与x互质的数有t1 = ans-ans/x个
ans范围内与y互质的数有t2 = ans-ans/y个
因为x,y都是质数,所以x的倍数与y互质,y的倍数与x互质
我们要判断ans范围内是否存在至少cnt1+cnt2个数满足条件
即找到与x或y互质的数的个数,可知为t3 = ans-ans/(x*y)
所以只需要满足以下三个条件,则说明当前的数符合要求
1、 t1>=cnt1
2、 t2>=cnt2
3 、t3>=cnt1+cnt2
注意结果可能会非常大,所以二分的上界要选好,我是直接选的long long最大值
代码如下:
#include <bits/stdc++.h>
#define LL long long
#define MAXN 0x7fffffffffffffff
using namespace std;
LL fun(LL m, LL x) {
return m-m/x;
}
int main(void) {
LL p, q, x, y, cnt1, cnt2, cnt3, l, r, m;
cin >> p >> q >> x >> y;
l = 1ll;
r = MAXN;
while(l < r) {
m = (l+r)>>1;
cnt1 = fun(m, x);
cnt2 = fun(m, y);
cnt3 = fun(m, x*y);
//printf("cnt1 = %lld\tcnt2 = %lld\tcnt3 = %lld\n", cnt1, cnt2, cnt3);
if(cnt1>=p && cnt2>=q && cnt3>=(p+q))
r = m;
else l = m+1;
//printf("l = %lld\tr = %lld\n", l, r);
}
cout << l << endl;
return 0;
}