hdu6286

题目链接

给定两个区间,这两个区间内分别取x,y,求x * y是2018倍数的方案数。

2018的因数只有1、2、1009、、2018四个,所以想到左右区间找这几个因数的倍数,然后左右相乘再处理,组合的思想,分类讨论两个区间。需要求出某区间内某个数的倍数的个数,边界值的处理需要注意。。。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<map>
using namespace std;
typedef long long ll;
const int maxn = 1e9 + 10;



ll cal(int a, int b, int base)        //返回[a,b]区间内base的倍数的个数
{
    ll l = (a - 1) / base;
    ll r = b / base;
    return r - l;
}


/*初始版本,写法有点啰嗦
void cal(int a, int b, ll& n2018, ll& n1009, ll& even)
{

    ll left = (a - 1) / 2018;
    ll right = b / 2018;
    ll ans = right - left;
    n2018 = ans;
    //cout << n2018 << endl;
    left = (a - 1) / 1009;
    right = b / 1009;
    ans = right - left;
    n1009 = ans;
    //cout << n1009 << endl;
    left = (a - 1) / 2;
    right = b / 2;
    ans = right - left;
    even = ans;
    //cout << even << endl;
}
*/


int main()
{

    ll a, b, c, d;
    while(scanf("%lld", &a) != EOF)
    {
        scanf("%lld%lld%lld", &b, &c, &d);
        ll l2018, l1009, leven;
        ll r2018, r1009, reven;

        l2018 = cal(a, b, 2018);
        l1009 = cal(a, b, 1009);
        leven = cal(a, b, 2);

        r2018 = cal(c, d, 2018);
        r1009 = cal(c, d, 1009);
        reven = cal(c, d, 2);
        //cal(a, b, l2018, l1009, leven);
        //cal(c, d, r2018, r1009, reven);

        ll ans = l2018 * (d - c + 1) + (l1009 - l2018) * reven + (leven - l2018) * r1009 + (b - a + 1 - leven - l1009 + l2018) * r2018;
        printf("%lld\n", ans);
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值