K.2018
题目描述
Given a, b, c, d , find out the number of pairs of integers ( x, y ) where a ≤ x ≤ b, c ≤ y ≤ d and x · y is a multiple of 2018.
输入
The input consists of several test cases and is terminated by end-of-file.
Each test case contains four integers a, b, c, d
Each test case contains four integers a, b, c, d
输出
For each test case, print an integer which denotes the result.
• 1 ≤ a ≤ b ≤ 109 , 1 ≤ c ≤ d ≤ 109
• The number of tests cases does not exceed 104 .
• 1 ≤ a ≤ b ≤ 109 , 1 ≤ c ≤ d ≤ 109
• The number of tests cases does not exceed 104 .
样例输入
1 2 1 2018
1 2018 1 2018
1 1000000000 1 1000000000
样例输出
3
6051
1485883320325200
题意:给定区间[a,b]、[c,d],问有多少对有序数组(x,y)(x∈[a,b],y∈[c,d])使得x*y是2018的倍数
思路:2018=2*1009(分解质因数),则对x分类讨论:1)仅为2的倍数;2)仅为1009的倍数;3)即为2又为1009的倍数;4)既不为2又不为1009的倍数
等价于如下分类讨论:
1.若x是偶数:1)若x是1009的倍数,则y可为[c,d]中任意数; 2)若x不是1009的倍数,则y必定为[c,d]中1009的倍数
2.若x是奇数:1)若x是1009的倍数,则y必定为[c,d]中2的倍数; 2)若x不是1009的倍数,则y必定为[c,d]中2018的倍数
#include <iostream> #include<cstring> #include<string> #include<cstdio> #include<algorithm> #include<cmath> #define ll long long using namespace std; int main() { ll a,b,c,d; while(cin>>a>>b>>c>>d) { ll s1=b-a+1; ll s2=d-c+1; ll s1_o=b/2-(a-1)/2; ll s1_1009=b/1009-(a-1)/1009; /*int x=b/2018-(a-1)/2018; ans+=x*s2; x=s1_o-x; ans+=x*(d/1009-(c-1)/1009); x=s1_1009-(b/2018-(a-1)/2018); ans+=x*(d/2-(c-1)/2); x=s1-s1_o-x; ans+=x*(d/2018-(c-1)/2018);*/ ll x1,x2,x3,x4; x1=(b/2018-(a-1)/2018)*s2; x2=(s1_o-(b/2018-(a-1)/2018))*(d/1009-(c-1)/1009); x3=(s1_1009-(b/2018-(a-1)/2018))*(d/2-(c-1)/2); x4=((s1-s1_o)-(s1_1009-(b/2018-(a-1)/2018)))*(d/2018-(c-1)/2018); printf("%lld ",x1+x2+x3+x4); } return 0; }