QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#424867#8669. 正方形计数JCY_100 ✓1604ms3864kbC++145.4kb2024-05-29 19:12:542024-05-29 19:12:54

Judging History

你现在查看的是最新测评结果

  • [2024-05-29 19:12:54]
  • 评测
  • 测评结果:100
  • 用时:1604ms
  • 内存:3864kb
  • [2024-05-29 19:12:54]
  • 提交

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"