QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#424865 | #8669. 正方形计数 | JCY_ | 10 | 546ms | 3836kb | C++14 | 5.4kb | 2024-05-29 19:11:16 | 2024-05-29 19:11:17 |
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, (b - c - a) % a, 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: 202ms
memory: 3488kb
input:
4 131 603 131 1828 1919 1828 1919 603
output:
361182910200
result:
ok 1 number(s): "361182910200"
Test #2:
score: 0
Accepted
time: 0ms
memory: 3620kb
input:
4 239 211 239 962 261 962 261 211
output:
1498772
result:
ok 1 number(s): "1498772"
Test #3:
score: 0
Accepted
time: 546ms
memory: 3632kb
input:
4 0 0 0 2000 2000 2000 2000 0
output:
1336001667000
result:
ok 1 number(s): "1336001667000"
Test #4:
score: 0
Accepted
time: 1ms
memory: 3836kb
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: 3624kb
input:
4 0 100 100 200 200 100 100 0
output:
34001650
result:
ok 1 number(s): "34001650"
Subtask #2:
score: 0
Runtime Error
Test #6:
score: 0
Runtime Error
input:
3 131 603 131 1828 1919 603
output:
result:
Subtask #3:
score: 0
Runtime Error
Test #11:
score: 0
Runtime Error
input:
8 0 13 4 15 15 15 15 6 13 1 12 0 5 0 0 6
output:
result:
Subtask #4:
score: 0
Skipped
Dependency #3:
0%
Subtask #5:
score: 0
Skipped
Dependency #4:
0%
Subtask #6:
score: 0
Skipped
Dependency #1:
100%
Accepted
Dependency #2:
0%