Codeforces Gym100425 A. Luggage Distribution

A. Luggage Distribution
time limit per test
1 second
memory limit per test
128 megabytes
input
standard input
output
standard output

All provident tourists know about low-cost airlines. Those who used them at least once also know that their airfare usually includes neither lunch nor luggage.

Naturally, tourists don’t want to overpay luggage fee, therefore they distribute their luggage so that it satisfies all airline requirements.

A certain tourist prepaid three luggage slots. Then he calculated the number of different ways K to distribute weight N among these three slots so that all luggage is packed, none of the slots are empty and all weights are integers. The order of the slots does not matter, so, for example, two distributions 2,  2,  1 and 2,  1,  2 are considered the same.

After landing, the tourist realised that the airline lost all his luggage! And while filling in a lost and found application, he found out that he does not remember the weight of each slot. He remembered only the fact that the number of ways K to pack the luggage was at least L and did not exceed R.

You need to calculate number of possible integer total weights N that could have been in the tourist’s luggage.

Input

The single line of input holds two integer numbers L and R (1 ≤ L ≤ R ≤ 1017): the minimum and maximum number of ways to distribule the luggage in three slots.

Output

Output a single integer: the number of possible total weigths N that could have been carried by the tourist.

Sample test(s)
Input
2 4
Output
3
Note

In the example, the tourist could have carried the total weight of 5, 6 or 7.

题意

把总量 X 的行李分成三份,有N种分法,现在给出 N 的范围L,R,问所有可能的 X ({1,2,3},{1,3,2},{2,1,3}...)看作一种分法

题解

看起来似乎是个dp。。对于 N 件物品,每个位置最少分1件,还剩N3件,这 N3 件可以放在一个位置上,就是1种分法,可以放在2个位置上,有 [N32] 种分法,分在3个位置就是 dp[N3] ,也就是说 dp[N]=1+[N32]+dp[N3] ,带入之后就是 dp[N]=1+[N32]+1+[N62]+... ,整理之后就是 [N3]+sum([x32])+sum([x62]) ,其中 sum(x) 是公差为 3 的,首相为1 2 3末项为 x 的等差数列前n项和。查询一件行李分法的操作时间复杂度可看作是 O(1) 的,打表发现 1095445116 件行李的分法刚好超过 1017 种,于是就可以在区间 [1,1095445116] 上进行二分。单次查询最多循环57次。超快。。。(WA了一发。。如果能熟练的写好二分也是挺不容易的。。我还是太弱了。。)

代码

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#define fout freopen("out.txt","w",stdout)
#define fin freopen("in.txt","r",stdin)


using namespace std;
int MAX=1095445116;
long long sum(long long x)
{
    if(x<=0)
        return 0LL;
    if(x%3)
        return ((x/3+1)*(x+x%3))/2;
    else
        return x*(3+x)/6;
}
long long ans(int x)
{
    return x/3+sum((x-3)/2)+sum((x-6)/2);
}
int low(long long F)
{
    unsigned int l=0,r=1095445116;
    unsigned int m=(l+r)/2;
    while(l<m)
    {
        if(ans(m)<F)
            l=m;
        else
            r=m;
        m=(l+r)/2;
    }
    return (int)l+1;
}
int up(long long F)
{
    unsigned int l=0,r=1095445116;
    unsigned int m=(l+r)/2;
    while(l<m)
    {
        if(ans(m)>F)
            r=m;
        else
            l=m;
        m=(l+r)/2;
    }
    return (int)l;
}
long long L,R;
int main()
{
    scanf("%I64d%I64d",&L,&R);
    printf("%d\n",up(R)-low(L)+1);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值