POJ3484

Showstopper

Solution sketch

觀察一下被reference的次數累積和(prefix sum),找出從偶數和變成奇數和的點就是答案了!

注意整除問題QAQ

AC code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#include <algorithm>
#include <climits>
#include <cstdio>
#include <vector>
using namespace std;
typedef long long ll;
struct Data {
ll x, y, z;
};
vector<Data> inp;
ll ans_sum;
bool isOdd(ll mid)
{
ll sum = 0;
ll cnt = 0;
for (int i = 0; i < (int)inp.size(); i++) {
if (min(inp[i].y, mid) < inp[i].x)
continue;
ll tmp = (min(inp[i].y, mid) - inp[i].x) / inp[i].z + 1;
if (inp[i].x <= mid && mid <= inp[i].y && (mid - inp[i].x) % inp[i].z == 0) // here QQ
cnt++;
sum += tmp;
}
ans_sum = cnt;
return sum % 2 == 1;
}
int main()
{
char str[10000];
bool last = true;
while (last) {
inp.clear();
while (1) {
if (fgets(str, 10000, stdin) == NULL) {
last = false;
break;
}
if (str[0] == '\n')
break;
ll x, y, z;
sscanf(str, "%lld %lld %lld", &x, &y, &z);
inp.push_back(Data({x, y, z}));
}
if (inp.size() == 0)
continue;
ll l = 0, r = LLONG_MAX;
while (r - l > 1) {
ll mid = l + (r - l) / 2;
// printf("%lld %lld %lld\n", l, mid, r);
if (isOdd(mid))
r = mid;
else
l = mid;
}
if (r == LLONG_MAX)
printf("no corruption\n");
else {
isOdd(r);
printf("%lld %lld\n", r, ans_sum);
}
}
return 0;
}