QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#424867 | #8669. 正方形计数 | JCY_ | 100 ✓ | 1604ms | 3864kb | C++14 | 5.4kb | 2024-05-29 19:12:54 | 2024-05-29 19:12:54 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
using ld = long double;
using i128 = __int128;
using u128 = unsigned __int128;
template <typename T>
void chkmax(T &x, const T &y) {
x = max(x, y);
}
template <typename T>
void chkmin(T &x, const T &y) {
x = min(x, y);
}
ll floor_div(ll x, ll y) { return x >= 0 ? x / y : (x + 1) / y - 1; }
ll ceil_div(ll x, ll y) { return x <= 0 ? x / y : (x - 1) / y + 1; }
struct vector2 {
ll x, y;
};
istream &operator>>(istream &is, vector2 &u) { return is >> u.x >> u.y; }
ostream &operator<<(ostream &os, const vector2 &u) {
return os << '(' << u.x << ", " << u.y << ')';
}
vector2 operator+(const vector2 &u, const vector2 &v) {
return {u.x + v.x, u.y + v.y};
}
vector2 operator-(const vector2 &u, const vector2 &v) {
return {u.x - v.x, u.y - v.y};
}
vector2 operator*(const vector2 &u, ll k) { return {u.x * k, u.y * k}; }
vector2 operator*(ll k, const vector2 &u) { return {u.x * k, u.y * k}; }
ll operator*(const vector2 &u, const vector2 &v) {
return u.x * v.y - u.y * v.x;
}
struct ray {
vector2 p, d;
ray() = default;
ray(const vector2 &_p, const vector2 &_d) : p{_p}, d{_d} {}
};
bool inter_is_left(const ray &l1, const ray &l2, const ray &l3) {
return (l1.d * l2.d) * (l3.d * (l1.p - l3.p)) >=
(l1.d * l3.d) * (l2.d * (l1.p - l2.p));
}
bool can_pop(ray l1, ray l2, const ray &l3) {
if (!(l1.d * l2.d)) return false;
if (l1.d * l2.d < 0) swap(l1, l2);
if (l1.d * l3.d < 0 || l3.d * l2.d < 0) return false;
return inter_is_left(l1, l2, l3);
}
vector<ray> half_plane_inter(const vector<ray> &vec) {
vector<ray> qu(vec.size());
int hd = 0, tl = -1;
for (auto &i : vec) {
if (hd < tl && can_pop(qu[hd], qu[tl], i)) continue;
while (hd < tl && can_pop(qu[tl - 1], i, qu[tl])) --tl;
while (hd < tl && can_pop(qu[hd + 1], i, qu[hd])) ++hd;
qu[++tl] = i;
}
if (tl - hd + 1 <= 2) return {};
if (qu[hd].d * qu[hd + 1].d <= 0) return {};
for (auto &i : vec)
if (!inter_is_left(qu[hd], qu[hd + 1], i)) return {};
return vector<ray>(qu.begin() + hd, qu.begin() + tl + 1);
}
namespace euclid {
template <typename T>
T qpow(T x, ll y) {
T ret;
for (; y; y >>= 1, x = x * x)
if (y & 1) ret = ret * x;
return ret;
}
template <typename T>
T solve(ll a, ll b, ll c, ll n, T U, T R) {
ll m = (a * n + c) / b;
if (!m) return qpow(R, n);
return qpow(R, (b - c - 1) / a) * U *
solve(b % a, a, (b - c - 1) % a, m - 1, R, qpow(R, b / a) * U) *
qpow(R, n - (b * m - c - 1) / a);
}
} // namespace euclid
struct node {
ll x, y, sum;
node() : x{}, y{}, sum{} {}
node(ll _x, ll _y, ll _sum) : x{_x}, y{_y}, sum{_sum} {}
};
node operator*(const node &u, const node &v) {
return {u.x + v.x, u.y + v.y, u.sum + v.sum + u.x * v.y};
}
ll solve(ll a, ll b, ll c, ll l, ll r) {
if (b < 0) {
a = -a;
b = -b;
c = -c;
}
c += (l - 1) * a;
r -= l - 1;
return floor_div(c, b) * r + floor_div(a, b) * (r + 1) * r / 2 +
euclid::solve((a % b + b) % b, b, (c % b + b) % b, r, node{1, 0, 0}, node{0, 1, 0}).sum;
}
ll calc(const ray &ry, ll l, ll r, bool flag) {
return (ry.p.y + 1) * (r - l + 1) + solve(ry.d.y, ry.d.x, -ry.p.x * ry.d.y - flag, l, r);
}
ll calc(vector<ray> vec) {
vec.emplace_back(vec[0]);
vec.emplace_back(vec[1]);
ll ret = 0;
for (int i = 1; i + 1 < (int)vec.size(); ++i) {
ray pre = vec[i - 1], cur = vec[i], nxt = vec[i + 1];
ll qu = pre.d * cur.d, pu = pre.d.x * ((cur.p - pre.p) * cur.d) + pre.p.x * qu;
ll qv = cur.d * nxt.d, pv = cur.d.x * ((nxt.p - cur.p) * nxt.d) + cur.p.x * qv;
if (cur.d.x > 0) {
ll l = ceil_div(pu, qu);
ll r = (nxt.d.x <= 0 ? floor_div(pv, qv) : ceil_div(pv, qv) - 1);
if (l <= r) ret -= calc(cur, l, r, true);
} else if (cur.d.x < 0) {
ll l = ceil_div(pv, qv);
ll r = (pre.d.x >= 0 ? floor_div(pu, qu) : ceil_div(pu, qu) - 1);
if (l <= r) ret += calc(cur, l, r, false);
}
}
return ret;
}
constexpr int MAXN = 12, INF = 0x3f3f3f3f;
int n;
vector2 pt[MAXN];
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n;
int mnx = INF, mxx = -INF, mny = INF, mxy = -INF;
for (int i = 1; i <= n; ++i) {
cin >> pt[i];
chkmin(mnx, (int)pt[i].x);
chkmax(mxx, (int)pt[i].x);
chkmin(mny, (int)pt[i].y);
chkmax(mxy, (int)pt[i].y);
}
int lim = min(mxx - mnx, mxy - mny);
reverse(pt + 1, pt + n + 1);
pt[n + 1] = pt[1];
ll ans = 0;
for (int x = 1; x <= lim; ++x) {
for (int y = 0; x + y <= lim; ++y) {
vector<ray> vec;
for (int i = 1; i <= n; ++i) {
vector2 d = pt[i + 1] - pt[i];
if (vector2{y, -x} * d > 0 && d * vector2{x, y} >= 0) {
vec.emplace_back(pt[i], d);
} else if (vector2{x, y} * d > 0 && d * vector2{-y, x} >= 0) {
vec.emplace_back(pt[i] - vector2{x, y}, d);
} else if (vector2{-y, x} * d > 0 && d * vector2{-x, -y} >= 0) {
vec.emplace_back(pt[i] - vector2{x - y, x + y}, d);
} else {
vec.emplace_back(pt[i] + vector2{y, -x}, d);
}
}
vec = half_plane_inter(vec);
if (!vec.empty()) ans += calc(vec);
}
}
cout << ans << "\n";
return 0;
}
/*
g++ A.cpp -o A -std=c++14 -O2 -Wall -Wextra -Wshadow -g -fsanitize=address,undefined
*/
Details
Tip: Click on the bar to expand more detailed information
Subtask #1:
score: 10
Accepted
Test #1:
score: 10
Accepted
time: 201ms
memory: 3552kb
input:
4 131 603 131 1828 1919 1828 1919 603
output:
361182910200
result:
ok 1 number(s): "361182910200"
Test #2:
score: 0
Accepted
time: 1ms
memory: 3632kb
input:
4 239 211 239 962 261 962 261 211
output:
1498772
result:
ok 1 number(s): "1498772"
Test #3:
score: 0
Accepted
time: 540ms
memory: 3656kb
input:
4 0 0 0 2000 2000 2000 2000 0
output:
1336001667000
result:
ok 1 number(s): "1336001667000"
Test #4:
score: 0
Accepted
time: 0ms
memory: 3592kb
input:
4 36 771 36 786 672 786 672 771
output:
427720
result:
ok 1 number(s): "427720"
Test #5:
score: 0
Accepted
time: 4ms
memory: 3556kb
input:
4 0 100 100 200 200 100 100 0
output:
34001650
result:
ok 1 number(s): "34001650"
Subtask #2:
score: 25
Accepted
Test #6:
score: 25
Accepted
time: 182ms
memory: 3628kb
input:
3 131 603 131 1828 1919 603
output:
63739309181
result:
ok 1 number(s): "63739309181"
Test #7:
score: 0
Accepted
time: 0ms
memory: 3556kb
input:
3 239 211 239 962 261 211
output:
353073
result:
ok 1 number(s): "353073"
Test #8:
score: 0
Accepted
time: 296ms
memory: 3556kb
input:
3 0 0 0 2000 2000 0
output:
222889277611
result:
ok 1 number(s): "222889277611"
Test #9:
score: 0
Accepted
time: 0ms
memory: 3556kb
input:
3 36 771 36 786 672 771
output:
98847
result:
ok 1 number(s): "98847"
Test #10:
score: 0
Accepted
time: 1ms
memory: 3860kb
input:
3 0 0 0 100 100 0
output:
1473186
result:
ok 1 number(s): "1473186"
Subtask #3:
score: 15
Accepted
Test #11:
score: 15
Accepted
time: 0ms
memory: 3620kb
input:
8 0 13 4 15 15 15 15 6 13 1 12 0 5 0 0 6
output:
4047
result:
ok 1 number(s): "4047"
Test #12:
score: 0
Accepted
time: 0ms
memory: 3620kb
input:
8 0 4 1 15 2 15 15 14 15 4 14 0 1 0 0 2
output:
4200
result:
ok 1 number(s): "4200"
Test #13:
score: 0
Accepted
time: 0ms
memory: 3820kb
input:
5 7 15 15 13 15 0 3 0 0 15
output:
3635
result:
ok 1 number(s): "3635"
Test #14:
score: 0
Accepted
time: 0ms
memory: 3508kb
input:
8 0 12 2 14 7 15 13 15 15 10 15 1 8 0 0 0
output:
4511
result:
ok 1 number(s): "4511"
Test #15:
score: 0
Accepted
time: 0ms
memory: 3592kb
input:
6 0 11 3 15 7 15 15 12 10 0 0 0
output:
3006
result:
ok 1 number(s): "3006"
Test #16:
score: 0
Accepted
time: 0ms
memory: 3816kb
input:
5 0 0 0 2 1 2 2 1 2 0
output:
4
result:
ok 1 number(s): "4"
Subtask #4:
score: 20
Accepted
Dependency #3:
100%
Accepted
Test #17:
score: 20
Accepted
time: 25ms
memory: 3816kb
input:
8 49 299 144 300 300 260 250 15 115 0 30 0 23 19 0 85
output:
443602646
result:
ok 1 number(s): "443602646"
Test #18:
score: 0
Accepted
time: 29ms
memory: 3616kb
input:
8 0 133 103 300 130 300 257 294 297 227 300 150 277 40 161 4
output:
351466521
result:
ok 1 number(s): "351466521"
Test #19:
score: 0
Accepted
time: 27ms
memory: 3824kb
input:
8 76 286 114 300 300 300 300 205 291 0 47 0 4 57 2 235
output:
605026927
result:
ok 1 number(s): "605026927"
Test #20:
score: 0
Accepted
time: 27ms
memory: 3624kb
input:
8 0 102 40 274 282 300 300 234 267 0 34 0 6 57 0 86
output:
497330741
result:
ok 1 number(s): "497330741"
Test #21:
score: 0
Accepted
time: 26ms
memory: 3784kb
input:
7 0 288 156 300 212 300 265 176 300 86 278 0 0 36
output:
446722651
result:
ok 1 number(s): "446722651"
Subtask #5:
score: 15
Accepted
Dependency #4:
100%
Accepted
Test #22:
score: 15
Accepted
time: 148ms
memory: 3552kb
input:
5 257 800 766 800 800 353 667 0 42 0
output:
18881369614
result:
ok 1 number(s): "18881369614"
Test #23:
score: 0
Accepted
time: 148ms
memory: 3780kb
input:
8 691 800 737 795 800 651 372 98 136 266 118 318 24 629 12 753
output:
8760058886
result:
ok 1 number(s): "8760058886"
Test #24:
score: 0
Accepted
time: 100ms
memory: 3820kb
input:
8 718 800 740 800 800 726 800 670 711 367 595 150 86 0 57 136
output:
3064355626
result:
ok 1 number(s): "3064355626"
Test #25:
score: 0
Accepted
time: 190ms
memory: 3620kb
input:
8 0 347 16 449 364 798 674 800 750 800 797 14 195 0 0 70
output:
23587042437
result:
ok 1 number(s): "23587042437"
Test #26:
score: 0
Accepted
time: 249ms
memory: 3864kb
input:
8 322 800 596 800 686 777 800 280 764 69 396 0 46 179 0 660
output:
23185884331
result:
ok 1 number(s): "23185884331"
Subtask #6:
score: 15
Accepted
Dependency #1:
100%
Accepted
Dependency #2:
100%
Accepted
Dependency #3:
100%
Accepted
Dependency #4:
100%
Accepted
Dependency #5:
100%
Accepted
Test #27:
score: 15
Accepted
time: 1373ms
memory: 3564kb
input:
8 0 1150 314 2000 1101 2000 1617 1607 1778 551 738 0 607 10 0 1011
output:
577130875850
result:
ok 1 number(s): "577130875850"
Test #28:
score: 0
Accepted
time: 1508ms
memory: 3800kb
input:
8 0 1841 1526 2000 1981 1680 1968 678 1893 26 973 0 616 315 524 434
output:
735496008519
result:
ok 1 number(s): "735496008519"
Test #29:
score: 0
Accepted
time: 1164ms
memory: 3556kb
input:
6 0 258 10 2000 1730 2000 2000 1510 1973 0 0 129
output:
1203935109430
result:
ok 1 number(s): "1203935109430"
Test #30:
score: 0
Accepted
time: 1319ms
memory: 3560kb
input:
7 200 2000 1686 2000 1951 1878 2000 863 1422 0 21 0 0 1015
output:
1100462975231
result:
ok 1 number(s): "1100462975231"
Test #31:
score: 0
Accepted
time: 1604ms
memory: 3620kb
input:
8 701 2000 1449 2000 1847 1928 2000 1496 1987 668 1588 108 263 0 0 1985
output:
997591862206
result:
ok 1 number(s): "997591862206"
Test #32:
score: 0
Accepted
time: 1538ms
memory: 3660kb
input:
8 15 2000 1235 2000 1545 1886 1970 1526 1828 427 1238 97 372 0 0 1786
output:
816089046494
result:
ok 1 number(s): "816089046494"
Test #33:
score: 0
Accepted
time: 1080ms
memory: 3852kb
input:
7 0 1685 1331 2000 2000 1941 2000 1310 1757 631 21 113 0 575
output:
633230324466
result:
ok 1 number(s): "633230324466"
Test #34:
score: 0
Accepted
time: 889ms
memory: 3632kb
input:
8 0 650 0 1350 650 2000 1350 2000 2000 1350 2000 650 1350 0 650 0
output:
900037062925
result:
ok 1 number(s): "900037062925"