CodeForces 483B Friends and Presents(二分+容斥定理)

该题比赛的时候没能想到用二分优化,一直超时。    其实答案是一个单调函数, 对于一个答案m,如果m不符合条件,那么小于m的都不符合,反之亦然。

所以我们可以直接二分答案,然后关键是判断。    通过观察,可以发现,对于答案m,能被x除尽的个数是m/x,能被y除尽的个数是m/y。 那么可以用来给f1(朋友1)的个数就是m-m/x,用来给f2的个数就是m-m/y。但是还要注意两者都能除尽的个数是m/(x*y),这些数字是一定不能选的,如果f1和f2都可以分别满足且总的可选数也满足的话,那么当前m就可以满足答案。

细节参见代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn = 100000;
ll cnt1,cnt2,x,y,n,m,vis[maxn];
bool C(ll m) {
    ll xx = m - m/x;
    ll yy = m - m/y;
    ll both = m/(x*y);
    if(xx < cnt1 || yy < cnt2) return false;
    if(m - both >= cnt1+cnt2) return true;
    return false;
}
int main() {
    while(~scanf("%I64d%I64d%I64d%I64d",&cnt1,&cnt2,&x,&y)) {
        ll l=0, r=1e12, m;
        while(r > l) {
            m = (r+l)/2;
            if(C(m)) r = m;
            else l = m+1;
        }
        printf("%I64d\n",r);
    }
    return 0;
}



你可能感兴趣的:(codeforces,二分,ACM-ICPC,容斥定理)