题目链接

给你两个区间[a,b]  ,  [c,d]  ,x在[a,b]内,y在[c,d]内,求有多少种情况使得(x*y)%2018=0

思路:求出有多少个2018的倍数在[a,b]内,多少个2018的倍数在[c,d]内,多少个1009的倍数在[a,b]内,多少个1009的倍数在[c,d]内,多少个2的倍数在[a,b]内,多少个2的倍数在[c,d]内,然后这几个数字乘一乘 然后加和,记得去掉重复的就行了

[1,4036]  , [1,2018]

cnt1=4036/2018 - (1-1)/2018   //cnt1  代表  [a,b]内2018的倍数个数

cnt2=2018/2018 - (1-1)/2018   //cnt2  代表  [c,d]内2018的倍数个数

cnt3=4036/1009 - (1-1)/1009 - cnt1  //cnt3  代表  [a,b]内1009的倍数个数 - [a,b]内1009的倍数个数

cnt4=2018/2- (1-1)/2- cnt2  //cnt4  代表  [c,d]内2的倍数个数 - [c,d]内2018的倍数个数

cnt5=2018/1009 - (1-1)/1009 - cnt2  //cnt5  代表  [c,d]内1009的倍数个数 - [c,d]内1009的倍数个数

cnt6=4036/2- (1-1)/2- cnt1  //cnt6  代表  [a,b]内2的倍数个数 - [a,b]内2018的倍数个数

 

结果就是cnt1 * (d - c + 1) + cnt2 * ( b - a + 1 - cnt1) + cnt3 * cnt4 + cnt5 * cnt6;

#include <bits/stdc++.h>
typedef long long ll;
using namespace std; 
ll cal(ll a, ll b, ll c, ll d ) {
    ll cnt1, cnt2, cnt3, cnt4, cnt5, cnt6, ans = 0;
    cnt1 = b / 2018 - (a - 1) / 2018;
    ans += cnt1 * (d - c + 1);

    cnt2 = d / 2018 - (c - 1) / 2018;
    ans += cnt2 * (b - a + 1 - cnt1);

    cnt3 = b / 1009 - (a - 1) / 1009 - cnt1;
    cnt4 = d / 2 - (c - 1) / 2 - cnt2;
    ans += cnt4 * cnt3;

    cnt5 = d / 1009 - (c - 1) / 1009 - cnt2;
    cnt6 = b / 2 - (a - 1 ) / 2 - cnt1;
    ans += cnt5 * cnt6;

    return ans;
}
int main() {
    ll a, b, c, d;
    while(~scanf("%lld%lld%lld%lld", &a, &b, &c, &d)) {
        printf("%lld\n", cal(c, d, a, b));
    }
    return 0;
}