URAL 1720 Summit Online Judge 乱搞题

题意:

每场比赛有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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值