-
Notifications
You must be signed in to change notification settings - Fork 0
/
diophantine.cpp
160 lines (147 loc) · 3.44 KB
/
diophantine.cpp
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#include <bits/stdc++.h>
using namespace std;
long long extended_euclidean(long long a, long long b, long long &x, long long &y) {
long long xa = 1;
long long ya = 0;
x = 0;
y = 1;
while (a % b != 0) {
long long newb = a % b;
long long q = a / b;
long long newx = xa - x * q;
long long newy = ya - y * q;
xa = x;
ya = y;
x = newx;
y = newy;
a = b;
b = newb;
}
return b;
}
long long gcd(long long a, long long b) {
return b != 0 ? gcd(b, a % b) : a;
}
bool find_one(long long a, long long b, long long c, long long &x, long long &y) {
if (a == 0 && b == 0) {
return c == 0;
}
long long d = extended_euclidean(abs(a), abs(b), x, y);
if (abs(c) % d != 0) {
return false;
}
if (a < 0) {
x *= -1;
}
if (b < 0) {
y *= -1;
}
x *= c / d;
y *= c / d;
return true;
}
long long count_solutions(long long a, long long b, long long c, long long min_x, long long max_x, long long min_y,
long long max_y) {
long long x, y;
if (a == 0 && b == 0) {
if (c == 0) {
return (max_x - min_x + 1) * (max_y - min_y + 1);
} else {
return 0;
}
}
if (a == 0) {
if (abs(c) % abs(b) == 0) {
y = c / b;
if (min_y <= y && y <= max_y) {
return (max_x - min_x + 1);
} else {
return 0;
}
} else {
return 0;
}
}
if (b == 0) {
if (abs(c) % abs(a) == 0) {
x = c / a;
if (min_x <= x && x <= max_x) {
return (max_y - min_y + 1);
} else {
return 0;
}
} else {
return 0;
}
}
if (!find_one(a, b, c, x, y)) {
return 0;
}
long long x0 = x;
long long y0 = y;
long long d = gcd(abs(a), abs(b));
a /= d;
b /= d;
long long cnt = (min_x - x) / b;
x = x + cnt * b;
if (x < min_x) {
x += abs(b);
}
if (x > max_x) {
return 0;
}
long long x1l = x;
cnt = (max_x - x) / b;
x = x + cnt * b;
if (x > max_x) {
x -= abs(b);
}
long long x1r = x;
if (x1l > x1r) {
swap(x1l, x1r);
}
x = x0;
y = y0;
cnt = (min_y - y) / a;
y = y + cnt * a;
x = x - cnt * b;
if (y < min_y) {
y += abs(a);
x -= abs(b);
}
if (y > max_y) {
return 0;
}
long long x2l = x;
cnt = (max_y - y) / a;
y = y + cnt * a;
x = x - cnt * b;
if (y > max_y) {
y -= abs(a);
x += abs(b);
}
long long x2r = x;
if (x2l > x2r) {
swap(x2l, x2r);
}
// assert(min_x <= x1l && x1l <= max_x);
// assert(min_x <= x1r && x1r <= max_x);
// assert(min_x <= x2l && x2l <= max_x);
// assert(min_x <= x2r && x2r <= max_x);
long long xl = max(x1l, x2l);
long long xr = min(x1r, x2r);
if (xl > xr) {
return 0;
}
return (xr - xl) / abs(b) + 1;
}
int main() {
std::ios_base::sync_with_stdio(false);
// freopen("/Users/milenkoviclazar/sandbox/competitive_programming/input.in", "r", stdin);
long long a, b, c, x_min, x_max, y_min, y_max;
cin >> a >> b >> c >> x_min >> x_max >> y_min >> y_max;
a = -a;
b = -b;
cout << count_solutions(a, b, c, x_min, x_max, y_min, y_max) << endl;
return 0;
}