给你两个区间[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;
}