CCPC 2018 湖南全国邀请赛 hdu 6286 2018

题意:给定a,b,c,d。问有多少对a<=x<=b , c<=y<=d x*y是2018的倍数

思路:2018只有四个因子,1,2, 1009, 2018

答案分为四个部分

1、x是2018的倍数有r1对 。r1指[c,d]之间有多少个1的倍数

2、x是1009的倍数(此处排除2018的倍数) 有reven对。 reven指[c,d]之间有多少个2的倍数

3、x是2的倍数(此处排除2018的倍数)有r1009对 。r1009指[c,d]之间有多少个1009的倍数

4、x是1 (此处减去2的倍数、减去1009的倍数、加上2018的倍数)。有r2018对 指[c,d]之间有多少个2018的倍数

所以只需要计算在区间里有多少个倍数

LL calc(int a,int b,int x) //计算区间a,b里有多少个x的倍数
{
    int left=a/x;
    int right=b/x;
    LL ans=right-left;
    if(a%x==0) ans+=1; //若左边界为x的整数倍,需要+1
    return ans;
}

基础不牢固,这个写了好久,还忘记了边界。

最终答案粗心把第三项和第四项的乘数敲反了居然过了那么多样例,也是惊了,以后比赛写题一定要两个人一起写!长一点的式子一定要先写在纸上!

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




/*
void solve()
{
    int t;
    for(int i = 1; i < maxn; i++)
    {
        t = i % 1009 == 0 ? 1 : 0;
        sum[i] = sum[i - 1] + t;
        t = i % 2018 == 0 ? 1 : 0;
        sum2[i] = sum2[i - 1] + t;
        t = i % 2 == 0 ? 1 : 0;
        even[i] = even[i - 1] + t;
    }
}*/

void cal(int a, int b, ll& n2018, ll& n1009, ll& even)
{
    ll left = a / 2018;
    ll right = b / 2018;
    ll ans = right - left;
    if(a%2018==0) ans+=1;           //左边是整数倍的情况 right-left会漏掉一个1
    n2018 = ans;
   // cout << n2018 << endl;
    left = a / 1009;
    right = b / 1009;
    ans = right - left;
    if(a%1009==0) ans+=1;
    n1009 = ans;
    //cout << n1009 << endl;
    left = a / 2;
    right = b / 2;
    ans = right - left;
    if(a%2==0) ans+=1;
    even = ans;
   // cout << even << endl;
}
LL calc(int a,int b,int x)
{
    int left=a/x;
    int right=b/x;
    LL ans=right-left;
    if(a%x==0) ans+=1;
    return ans;
}

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;
        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;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值