URAL 1720 Summit Online Judge 乱搞题

来源:互联网 发布:视频后期特效软件 编辑:程序博客网 时间:2024/06/05 18:45

题意:

每场比赛有x~y题,每一卷要求分为l~r题。每一卷的题数要求一样。

现在问你一卷内,可以包含一场或多场比赛的题,且刚好等于卷的大小,在l~r中有几个是可行的。

思路:

来源:http://www.cppblog.com/Yuan/archive/2011/08/01/152243.html?opt=admin

不过我按照上文博主的思路写了一发,就算用double也一样溢出,导致不能AC。

这里不得不说杰哥威武霸气。

首先我们二分出最后一个不会出现重叠的位置res。(其实可以直接算出来,在主函数中的注释便是)

二分的时候,我们要算x*mid > y*(mid-1)。转换一下,便可以得到y>(y-x)*mid,我们可以用二进制逐步计算(y-x)*mid的值,这样就算相乘溢出也可以处理了(代码中的mul函数)。

得到res后,最后进行统计即可。

code:

#include <bits/stdc++.h>using namespace std;typedef unsigned long long uLL;const uLL INF = 1e18+5;uLL res;uLL x, y, l, r;template <class T> T mul(T a, T b) {    T ret = 0;    while(a) {        if(a& 1) {            ret += b;            if(ret > INF) return INF;        }        a >>= 1;b <<= 1;        if(b >= INF) {            if(a) return INF;            return ret;        }    }    return ret;}void Binary() {    uLL l = 1, r = y;    while(l <= r) {        uLL mid = (l+r)/2;        uLL tmp = mul(mid, y-x);        //if(x*mid > y*(mid-1)){        //这里可能溢出,改成下面的写法        if(y > tmp) {            res = mid;            l = mid+1;        }        else r = mid-1;    }}    uLL get(uLL val) {    uLL idxr = val/y;    uLL cnt = 0;    if(idxr >= res)         cnt = (1+res)*res/2*(y-x)+res+(val-res*y);    else {        cnt = (1+idxr)*idxr/2*(y-x)+idxr;        if(val%y != 0) {            uLL l = (1+idxr)*x;            cnt += (val >= l?val-l+1:0);        }    }    return cnt;}int main() {//freopen("cin.txt", "r", stdin);while(cin>>x>>y>>l>>r) {if(x > r) {cout<<"0"<<endl;continue;}if(x == y) {cout<<r/x-(l-1)/x<<endl;continue ;}        /*        res = y/(y-x);        if(y%(y-x) == 0) res--;        */Binary();uLL res1 = get(r), res2 = get(l-1);cout<<(res1-res2)<<endl;}    return 0;}



0 0