【链接】
【题意】【题解】
我们可以二分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#define LL long longusing 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< <