HDU - 6286
Posted houraisankaguya
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU - 6286相关的知识,希望对你有一定的参考价值。
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6286
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.
For each test case, print an integer which denotes the result.
## Constraint
* 1≤a≤b≤10^9,1≤c≤d≤10^9
* The number of tests cases does not exceed 10^4.
正解:容斥原理:
因为2018的因子只有1、2、1009、2018,所以只需计算以下五种情况:
1. [a,b]中2018的倍数,[c,d]为任意数
2. [c,d]中2018的倍数,[a,b]为任意数
3. [a,b]中2018的倍数且[c,d]中2018的倍数(为了1,2情况去重)
4. [a,b]中1009的奇数倍(偶数倍同1有重叠),[d,c]中2的倍数且不是2018的倍数
5. [c,d]中1009的奇数倍(偶数倍同2有重叠),[a,b]中2的倍数且不是2018的倍数
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<vector> 5 #include<queue> 6 #include<algorithm> 7 using namespace std; 8 typedef long long ll; 9 ll a, b, c, d; 10 ll solve(ll x) 11 12 x /= 1009; 13 if (x % 2) return x / 2 + 1; 14 return x / 2; 15 16 int main() 17 18 while (~scanf("%lld%lld%lld%lld", &a, &b, &c, &d)) 19 ll sum = 0; 20 sum += (b / 2018 - (a - 1) / 2018)*(d - c + 1); 21 sum += (d / 2018 - (c - 1) / 2018)*(b - a + 1); 22 sum -= (b / 2018 - (a - 1) / 2018)*(d / 2018 - (c - 1) / 2018); 23 sum += (solve(b) - solve(a - 1))*(d / 2 - (c - 1) / 2 - (d / 2018 - (c - 1) / 2018)); 24 sum += (solve(d) - solve(c - 1))*(b / 2 - (a - 1) / 2 - (b / 2018 - (a - 1) / 2018)); 25 printf("%lld\n", sum); 26 27 return 0; 28
非常规解法:
先暴力找出[0,2017]范围内所有满足i*j%2018=0的数对(i,j),这样的数对数目不超过6050个,
又有(i*j)%p=[(i%p)*(j%p)]%p,在这里i%p、j%p的值必然小于2018,若它们乘起来可被2018整除,就说明这样的i、j满足要求。
而我们又找出了所有2018内的数对(i,j),对于每一个(i,j),我们求出[a,b]间被2018整除余i的数字个数,乘以[c,d]间被2018整除余j的数字个数,将其累加起来即为答案。
补充:vjudge上没法直接交表,所以这里不得不把打表的过程写进去,导致编译器要选g++才可以过,c++会超时。
1 #pragma GCC optimize (3) 2 #include<vector> 3 #include<stack> 4 #include<bitset> 5 #include<cstdlib> 6 #include<cmath> 7 #include<set> 8 #include<list> 9 #include<deque> 10 #include<map> 11 #include<queue> 12 #include<iostream> 13 #include<cstdio> 14 #include<cstring> 15 #include<algorithm> 16 #define ull unsigned long long 17 using namespace std; 18 int ar[6051][2]; 19 inline int solve(int r, int chu, int mod) 20 21 if (r <= 0) return 0; 22 if (mod == 0) return r / chu; 23 if (r < mod) return 0; 24 if ((r - mod + 1) % chu == 0) return (r - mod + 1) / chu; 25 else return (r - mod + 1) / chu + 1; 26 27 int main() 28 29 ull ans; 30 int a, b, c, d, k = 0; 31 for (int i = 0; i <= 2017; i++) 32 for (int j = 0; j <= 2017; j++) 33 if ((i*j) % 2018 == 0) 34 ar[k][0] = i; 35 ar[k][1] = j; 36 k++; 37 38 39 40 while (scanf("%d%d%d%d", &a, &b, &c, &d) == 4) 41 ans = 0; 42 for (int i = 0; i <= 6050; i++) 43 ans += (ull)(solve(b, 2018, ar[i][0]) - solve(a - 1, 2018, ar[i][0]))*(solve(d, 2018, ar[i][1]) - solve(c - 1, 2018, ar[i][1])); 44 45 cout << ans << endl; 46 47 return 0; 48
以上是关于HDU - 6286的主要内容,如果未能解决你的问题,请参考以下文章
hdu 1847 Good Luck in CET-4 Everybody!(sg)
ruby なぜか布尔の验证〜存在がいつもエラーになる参考:http://qiita.com/diskshima/items/9c0b6286d68c0c13bb68