题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=6286
题目:
Problem Description
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.
Input
The input consists of several test cases and is terminated by end-of-file.
Each test case contains four integers a,b,c,d.
Output
For each test case, print an integer which denotes the result.
## Constraint
* 1≤a≤b≤109,1≤c≤d≤109
* The number of tests cases does not exceed 104.
Sample Input
1 2 1 2018
1 2018 1 2018
1 1000000000 1 1000000000
Sample Output
3
6051
1485883320325200
解题思路:
2018只能分解成1*2018和2*1009。
所以要求的二元组应该是下面四种形式:
a:(1k,2018k)A:(2018k,1k)
b(2k,1009k) B:(1009k,2k)
其中定义a1、a2表示可取值中有多少个是1的倍数(即k的数目),有多少个是2018的倍数,A1、A2同理。
为了少考虑a和b重复的二元组,b1、b2表示可取值中有多少个是2的倍数,有多少个是1009的奇数倍。B1、B2表示可取值中有多少个是1009的奇数倍(注意不要求错!!),有多少个是2的倍数。
(emmm好像定义的有些麻烦,其实b1定义成可取值中有多少个是2的倍数但不是2018的倍数可以简化式子,算了,就这么写吧,殊途同归)
最终得到式子:
ans = a1 * a2 + A1 * A2 - A1 * a2 + b1 * b2 + B1 * B2 - b2 * A1 - a2 * B1;
ac代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;
typedef long long ll;
ll a, b, c, d;
ll Count(ll a, ll b, ll x)
{
if(x == 1009)
{
ll m, n = b/x;
if(a%x == 0) m = a/x;
else m = a/x+1;
if(m > n) return 0;
else
{
if(m%2 == 0) return (n-m+1)/2;
else return (n-m+2)/2;
}
}
else return b/x - (a-1)/x;
}
int main()
{
//freopen("/Users/zhangkanqi/Desktop/11.txt","r",stdin);
while(scanf("%lld %lld %lld %lld", &a, &b, &c, &d) == 4)
{
ll a1, a2, A1, A2, b1, b2, B1, B2;
a1 = b - a + 1; a2 = Count(c, d, 2018);
A1 = Count(a, b, 2018); A2 = d - c + 1;
b1 = Count(a, b, 2); b2 = Count(c, d, 1009);//b2也可以直接用1009倍数的个数-2018倍数的个数,倔强的我还是坚持自己的写法
B1 = Count(a, b, 1009); B2 = Count(c, d, 2);
ll ans = a1 * a2 + A1 * A2 - A1 * a2 + b1 * b2 + B1 * B2 - b2 * A1 - a2 * B1;
cout << ans << endl;
}
return 0;
}