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 axb,cyd and xy 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

1ab10^9,1cd10^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 }

猜你喜欢

转载自www.cnblogs.com/HouraisanKaguya/p/11436839.html
hdu