// BEGIN: main.cpp #line 1 "main.cpp" // BEGIN: my_template.hpp #line 1 "my_template.hpp" #if defined(USE_PCH) #include #else #if defined(__GNUC__) #include #pragma GCC optimize("Ofast,unroll-loops") // 環境によってはコンパイル成功かつ実行時エラー #pragma GCC target("avx2,popcnt") #endif #include #include using namespace std; using ll = long long; using u8 = uint8_t; using u16 = uint16_t; using u32 = uint32_t; using u64 = uint64_t; using i128 = __int128; using u128 = unsigned __int128; using f128 = __float128; template constexpr bool dependent_false = false; template constexpr T infty = [] { static_assert(dependent_false, "infty is not defined"); return T{}; }(); template <> constexpr int infty = 1'010'000'000; template <> constexpr ll infty = 2'020'000'000'000'000'000; template <> constexpr u32 infty = infty; template <> constexpr u64 infty = infty; template <> constexpr i128 infty = i128(infty) * 2'000'000'000'000'000'000; template <> constexpr double infty = infty; template <> constexpr long double infty = infty; using pi = pair; using vi = vector; template using vc = vector; template using vvc = vector>; template using vvvc = vector>; template using vvvvc = vector>; template using pq_max = priority_queue; template using pq_min = priority_queue, greater>; #define vv(type, name, h, ...) \ vector> name(h, vector(__VA_ARGS__)) #define vvv(type, name, h, w, ...) \ vector>> name( \ h, vector>(w, vector(__VA_ARGS__))) #define vvvv(type, name, a, b, c, ...) \ vector>>> name( \ a, vector>>( \ b, vector>(c, vector(__VA_ARGS__)))) // https://trap.jp/post/1224/ #define FOR1(a) for (ll _ = 0; _ < ll(a); ++_) #define FOR2(i, a) for (ll i = 0; i < ll(a); ++i) #define FOR3(i, a, b) for (ll i = a; i < ll(b); ++i) #define FOR4(i, a, b, c) for (ll i = a; i < ll(b); i += (c)) #define FOR1_R(a) for (ll i = ll(a) - 1; i >= ll(0); --i) #define FOR2_R(i, a) for (ll i = ll(a) - 1; i >= ll(0); --i) #define FOR3_R(i, a, b) for (ll i = ll(b) - 1; i >= ll(a); --i) #define overload4(a, b, c, d, e, ...) e #define overload3(a, b, c, d, ...) d #define FOR(...) overload4(__VA_ARGS__, FOR4, FOR3, FOR2, FOR1)(__VA_ARGS__) #define FOR_R(...) overload3(__VA_ARGS__, FOR3_R, FOR2_R, FOR1_R)(__VA_ARGS__) #define all(x) (x).begin(), (x).end() #define len(x) ll(x.size()) #define elif else if #define eb emplace_back #define mp make_pair #define mt make_tuple #define fi first #define se second #define stoi stoll // require y > 0 template T floor(T x, T y) { return x / y - (x % y < 0); } // require y > 0 template T ceil(T x, T y) { return (x / y) + (x % y > 0); } // require y > 0 template T bmod(T x, T y) { T r = x % y; return (r < 0 ? r + y : r); } // require y > 0 template pair divmod(T x, T y) { T q = x / y, r = x % y; if (r < 0) --q, r += y; return {q, r}; } constexpr auto TEN = [] { array A{}; A[0] = 1; for (int i = 1; i < 20; ++i) A[i] = 10 * A[i - 1]; return A; }(); template T SUM(const U &A) { return std::accumulate(A.begin(), A.end(), T{}); } #define MIN(v) *min_element(all(v)) #define MAX(v) *max_element(all(v)) template inline long long LB(const C &c, const T &x) { return lower_bound(c.begin(), c.end(), x) - c.begin(); } template inline long long UB(const C &c, const T &x) { return upper_bound(c.begin(), c.end(), x) - c.begin(); } #define UNIQUE(x) sort(all(x)), x.erase(unique(all(x)), x.end()) template T POP(deque &que) { T a = que.front(); que.pop_front(); return a; } template T POP(priority_queue &que) { T a = que.top(); que.pop(); return a; } template T POP(vc &que) { T a = que.back(); que.pop_back(); return a; } template i128 binary_search(F check, i128 ok, i128 ng, bool check_ok = true) { if (check_ok) assert(check(ok)); while (1) { i128 x = (ok + ng) / 2; if (x == ok || x == ng) break; (check(x) ? ok : ng) = x; } return ok; } template double binary_search_real(F check, double ok, double ng, int iter = 100) { FOR(iter) { double x = (ok + ng) / 2; (check(x) ? ok : ng) = x; } return (ok + ng) / 2; } template inline bool chmax(T &a, const S &b) { T c = max(a, b); bool changed = (c != a); a = c; return changed; } template inline bool chmin(T &a, const S &b) { T c = min(a, b); bool changed = (c != a); a = c; return changed; } // ? は -1 vc s_to_vi(const string &S, char first_char) { vc A(S.size()); FOR(i, S.size()) { A[i] = (S[i] != '?' ? S[i] - first_char : -1); } return A; } template vc cumsum(const vc &A, int off = 1) { int N = A.size(); vc B(N + 1); FOR(i, N) { B[i + 1] = B[i] + A[i]; } if (off == 0) B.erase(B.begin()); return B; } // stable sort template vc argsort(const vc &A) { vc ids(len(A)); iota(all(ids), 0); sort(all(ids), [&](int i, int j) { return (A[i] == A[j] ? i < j : A[i] < A[j]); }); return ids; } // A[I[0]], A[I[1]], ... template vc rearrange(const vc &A, const vc &I) { vc B(len(I)); FOR(i, len(I)) B[i] = A[I[i]]; return B; } template void concat(vc &first, const Vectors &...others) { first.reserve(first.size() + (others.size() + ... + 0)); (first.insert(first.end(), others.begin(), others.end()), ...); } // i128 template , int> = 0> constexpr i128 abs(T x) { return x < 0 ? -x : x; } constexpr i128 gcd(i128 a, i128 b) { while (b != 0) { i128 c = a % b; a = b, b = c; } return abs(a); } #endif // END: my_template.hpp #line 2 "main.cpp" // BEGIN: other/io.hpp #line 1 "other/io.hpp" #define FASTIO // https://judge.yosupo.jp/submission/21623 namespace fastio { static constexpr uint32_t SZ = 1 << 17; char ibuf[SZ]; char obuf[SZ]; char out[100]; // pointer of ibuf, obuf uint32_t pil = 0, pir = 0, por = 0; bool input_eof = false; template constexpr bool is_signed_integer_v = is_signed_v || is_same_v; template struct unsigned_integer { using type = make_unsigned_t; }; template <> struct unsigned_integer { using type = u128; }; template <> struct unsigned_integer { using type = u128; }; template using unsigned_integer_t = typename unsigned_integer::type; [[noreturn]] inline void input_error(const char *message) { fputs(message, stderr); fputc('\n', stderr); exit(EXIT_FAILURE); } struct Pre { char num[10000][4]; constexpr Pre() : num() { for (int i = 0; i < 10000; i++) { int n = i; for (int j = 3; j >= 0; j--) { num[i][j] = n % 10 | '0'; n /= 10; } } } } constexpr pre; inline void load() { uint32_t n = pir - pil; memmove(ibuf, ibuf + pil, n); pil = 0; pir = n; if (input_eof) return; pir += fread(ibuf + pir, 1, SZ - pir, stdin); if (ferror(stdin)) input_error("fastio: input error"); if (feof(stdin)) { input_eof = true; // Allows the last token to end exactly at EOF without a trailing // whitespace. if (pir < SZ) ibuf[pir++] = '\n'; } } inline char get_char() { if (pil == pir) { load(); if (pil == pir) input_error("fastio: unexpected EOF"); } return ibuf[pil++]; } inline void flush() { fwrite(obuf, 1, por, stdout); por = 0; } void rd(char &c) { do c = get_char(); while (isspace(static_cast(c))); } void rd(string &x) { x.clear(); char c; do c = get_char(); while (isspace(static_cast(c))); do { x += c; c = get_char(); } while (!isspace(static_cast(c))); } template void rd_real(T &x) { string s; rd(s); x = stod(s); } template void rd_integer_slow(T &x) { char c; do c = get_char(); while (c < '-'); bool minus = 0; if constexpr (is_signed_integer_v) { if (c == '-') { minus = 1, c = get_char(); } } x = 0; assert('0' <= c && c <= '9'); while ('0' <= c && c <= '9') { x = x * 10 + (c & 15), c = get_char(); } assert(isspace(static_cast(c))); if constexpr (is_signed_integer_v) { if (minus) x = -x; } } template void rd_integer(T &x) { if (pil + 100 > pir) { load(); if (pil + 100 > pir) { rd_integer_slow(x); return; } } char c; do c = ibuf[pil++]; while (c < '-'); bool minus = 0; if constexpr (is_signed_integer_v) { if (c == '-') { minus = 1, c = ibuf[pil++]; } } x = 0; assert('0' <= c && c <= '9'); while ('0' <= c && c <= '9') { x = x * 10 + (c & 15), c = ibuf[pil++]; } assert(isspace(static_cast(c))); if constexpr (is_signed_integer_v) { if (minus) x = -x; } } template enable_if_t || is_same_v || is_same_v> rd( T &x) { rd_integer(x); } template enable_if_t || is_same_v> rd(T &x) { rd_real(x); } template void rd(pair &p) { rd(p.first), rd(p.second); } template void rd_tuple(T &t) { if constexpr (N < tuple_size::value) { auto &x = get(t); rd(x); rd_tuple(t); } } template void rd(tuple &tpl) { rd_tuple(tpl); } template void rd(array &x) { for (auto &d : x) rd(d); } template void rd(vc &x) { for (auto &d : x) rd(d); } template void read(T &...x) { (rd(x), ...); } inline void wt_range(const char *s, size_t n) { size_t i = 0; while (i < n) { if (por == SZ) flush(); size_t chunk = min(n - i, (size_t)(SZ - por)); memcpy(obuf + por, s + i, chunk); por += chunk; i += chunk; } } void wt(const char c) { if (por == SZ) flush(); obuf[por++] = c; } void wt(const char *s) { wt_range(s, strlen(s)); } void wt(const string &s) { wt_range(s.data(), s.size()); } template void wt_integer(T x) { if (por > SZ - 100) flush(); using U = unsigned_integer_t; U y = static_cast(x); if constexpr (is_signed_integer_v) { if (x < 0) { obuf[por++] = '-'; y = U(0) - y; } } int outi; for (outi = 96; y >= 10000; outi -= 4) { memcpy(out + outi, pre.num[y % 10000], 4); y /= 10000; } if (y >= 1000) { memcpy(obuf + por, pre.num[y], 4); por += 4; } else if (y >= 100) { memcpy(obuf + por, pre.num[y] + 1, 3); por += 3; } else if (y >= 10) { int q = (y * 103) >> 10; obuf[por] = q | '0'; obuf[por + 1] = (y - q * 10) | '0'; por += 2; } else obuf[por++] = y | '0'; memcpy(obuf + por, out + outi + 4, 96 - outi); por += 96 - outi; } template inline void wt_real(T x) { static char buf[1000]; int n = std::snprintf(buf, sizeof(buf), "%.15f", (double)x); wt_range(buf, (size_t)n); } template enable_if_t || is_same_v || is_same_v> wt( T x) { wt_integer(x); } template enable_if_t || is_same_v> wt(T x) { wt_real(x); } inline void wt(bool b) { wt(static_cast('0' + (b ? 1 : 0))); } template void wt(const pair &val) { wt(val.first); wt(' '); wt(val.second); } template void wt_tuple(const T &t) { if constexpr (N < tuple_size::value) { if constexpr (N > 0) wt(' '); wt(get(t)); wt_tuple(t); } } template void wt(const tuple &tpl) { wt_tuple(tpl); } template void wt(const array &val) { auto n = val.size(); for (size_t i = 0; i < n; i++) { if (i) wt(' '); wt(val[i]); } } template void wt(const vector &val) { auto n = val.size(); for (size_t i = 0; i < n; i++) { if (i) wt(' '); wt(val[i]); } } void print() { wt('\n'); } template void print(Head &&head, Tail &&...tail) { wt(forward(head)); ((wt(' '), wt(forward(tail))), ...); wt('\n'); } // gcc expansion. called automaticall after main. void __attribute__((destructor)) _d() { flush(); } } // namespace fastio using fastio::flush; using fastio::print; using fastio::read; #if defined(LOCAL) #define HDR "[DEBUG:", __func__, __LINE__, "]" #define SHOW(...) \ SHOW_IMPL(__VA_ARGS__, SHOW8, SHOW7, SHOW6, SHOW5, SHOW4, SHOW3, SHOW2, \ SHOW1) \ (__VA_ARGS__) #define SHOW_IMPL(_1, _2, _3, _4, _5, _6, _7, _8, NAME, ...) NAME #define SHOW1(x) print(HDR, #x, "=", (x)), flush() #define SHOW2(x, y) print(HDR, #x, "=", (x), #y, "=", (y)), flush() #define SHOW3(x, y, z) \ print(HDR, #x, "=", (x), #y, "=", (y), #z, "=", (z)), flush() #define SHOW4(x, y, z, w) \ print(HDR, #x, "=", (x), #y, "=", (y), #z, "=", (z), #w, "=", (w)), flush() #define SHOW5(x, y, z, w, v) \ print(HDR, #x, "=", (x), #y, "=", (y), #z, "=", (z), #w, "=", (w), #v, "=", \ (v)), \ flush() #define SHOW6(x, y, z, w, v, u) \ print(HDR, #x, "=", (x), #y, "=", (y), #z, "=", (z), #w, "=", (w), #v, "=", \ (v), #u, "=", (u)), \ flush() #define SHOW7(x, y, z, w, v, u, t) \ print(HDR, #x, "=", (x), #y, "=", (y), #z, "=", (z), #w, "=", (w), #v, "=", \ (v), #u, "=", (u), #t, "=", (t)), \ flush() #define SHOW8(x, y, z, w, v, u, t, s) \ print(HDR, #x, "=", (x), #y, "=", (y), #z, "=", (z), #w, "=", (w), #v, "=", \ (v), #u, "=", (u), #t, "=", (t), #s, "=", (s)), \ flush() #else #define SHOW(...) #endif #define INT(...) \ int __VA_ARGS__; \ read(__VA_ARGS__) #define LL(...) \ ll __VA_ARGS__; \ read(__VA_ARGS__) #define U32(...) \ u32 __VA_ARGS__; \ read(__VA_ARGS__) #define U64(...) \ u64 __VA_ARGS__; \ read(__VA_ARGS__) #define STR(...) \ string __VA_ARGS__; \ read(__VA_ARGS__) #define CHAR(...) \ char __VA_ARGS__; \ read(__VA_ARGS__) #define DBL(...) \ double __VA_ARGS__; \ read(__VA_ARGS__) #define VEC(type, name, size) \ vector name(size); \ read(name) #define VV(type, name, h, w) \ vector> name(h, vector(w)); \ read(name) void YES(bool t = 1) { print(t ? "YES" : "NO"); } void NO(bool t = 1) { YES(!t); } void Yes(bool t = 1) { print(t ? "Yes" : "No"); } void No(bool t = 1) { Yes(!t); } void yes(bool t = 1) { print(t ? "yes" : "no"); } void no(bool t = 1) { yes(!t); } void YA(bool t = 1) { print(t ? "YA" : "TIDAK"); } void TIDAK(bool t = 1) { YA(!t); } void Alice(bool t = 1) { print(t ? "Alice" : "Bob"); } void Bob(bool t = 1) { Alice(!t); }// END: other/io.hpp #line 3 "main.cpp" // BEGIN: geo/base.hpp #line 1 "geo/base.hpp" template struct Point { T x, y; Point() : x(0), y(0) {} template Point(A x, B y) : x(x), y(y) {} template Point(pair p) : x(p.fi), y(p.se) {} template Point(Point p) : x(p.x), y(p.y) { static_assert(!is_integral_v || is_integral_v); } Point operator+=(const Point p) { x += p.x, y += p.y; return *this; } Point operator-=(const Point p) { x -= p.x, y -= p.y; return *this; } Point operator+(Point p) const { return {x + p.x, y + p.y}; } Point operator-(Point p) const { return {x - p.x, y - p.y}; } bool operator==(Point p) const { return x == p.x && y == p.y; } bool operator!=(Point p) const { return x != p.x || y != p.y; } Point operator-() const { return {-x, -y}; } Point operator*(T t) const { return {x * t, y * t}; } Point operator/(T t) const { return {x / t, y / t}; } bool operator<(Point p) const { if (x != p.x) return x < p.x; return y < p.y; } T dot(const Point& other) const { return x * other.x + y * other.y; } T det(const Point& other) const { return x * other.y - y * other.x; } double norm() { return sqrtl(x * x + y * y); } double angle() { return atan2(y, x); } Point rotate(double theta) { static_assert(!is_integral::value); double c = cos(theta), s = sin(theta); return Point{c * x - s * y, s * x + c * y}; } Point rot90(bool ccw) { return (ccw ? Point{-y, x} : Point{y, -x}); } }; #ifdef FASTIO template void rd(Point& p) { fastio::rd(p.x), fastio::rd(p.y); } template void wt(Point& p) { fastio::wt(p.x); fastio::wt(' '); fastio::wt(p.y); } #endif // A -> B -> C と進むときに、左に曲がるならば +1、右に曲がるならば -1 template int ccw(Point A, Point B, Point C) { T x = (B - A).det(C - A); if (x > 0) return 1; if (x < 0) return -1; return 0; } template REAL dist(Point A, Point B) { REAL dx = REAL(A.x) - REAL(B.x); REAL dy = REAL(A.y) - REAL(B.y); return sqrt(dx * dx + dy * dy); } // ax+by+c template struct Line { T a, b, c; Line(T a, T b, T c) : a(a), b(b), c(c) {} Line(Point A, Point B) { a = A.y - B.y, b = B.x - A.x, c = A.x * B.y - A.y * B.x; } Line(T x1, T y1, T x2, T y2) : Line(Point(x1, y1), Point(x2, y2)) {} template U eval(Point P) { return U(a) * P.x + U(b) * P.y + U(c); } template T eval(U x, U y) { return a * x + b * y + c; } // 同じ直線が同じ a,b,c で表現されるようにする void normalize() { static_assert(is_same_v || is_same_v); T g = gcd(gcd(abs(a), abs(b)), abs(c)); a /= g, b /= g, c /= g; if (b < 0) { a = -a, b = -b, c = -c; } if (b == 0 && a < 0) { a = -a, b = -b, c = -c; } } bool is_parallel(Line other) { return a * other.b - b * other.a == 0; } bool is_orthogonal(Line other) { return a * other.a + b * other.b == 0; } bool is_same(Line other) { if (a * other.b != b * other.a) return 0; if (a * other.c != c * other.a) return 0; if (b * other.c != c * other.b) return 0; return 1; } }; template struct Segment { Point A, B; Segment(Point A, Point B) : A(A), B(B) {} Segment(T x1, T y1, T x2, T y2) : Segment(Point(x1, y1), Point(x2, y2)) {} bool contain(Point C) { T det = (C - A).det(B - A); if (det != 0) return 0; return (C - A).dot(B - A) >= 0 && (C - B).dot(A - B) >= 0; } Line to_line() { return Line(A, B); } }; template struct Circle { Point O; REAL r; Circle() {} Circle(Point O, REAL r) : O(O), r(r) {} Circle(REAL x, REAL y, REAL r) : O(x, y), r(r) {} template bool contain(Point p) { REAL dx = p.x - O.x, dy = p.y - O.y; return dx * dx + dy * dy <= r * r; } }; // END: geo/base.hpp #line 5 "main.cpp" /* 色 1 の円 色 2 の円 がある 色 1 の円の和集合面積は? 色 2 の円の和集合面積は? 色 1, 2 の円の和集合面積は? これができればいいか 実は書いたことないんですが そんなに難しくはないはずで 境界に現れる弧の寄与を足してくる タイブレイク大丈夫か? 完全に一致する円に注意する!! wow 長方形に制限みたいな要素も発生!? まあ、やるか... 中心が外側!! 修正できるか? */ // using Re = long double; // using Re = long double; using Re = long double; using RE = long double; const Re PI = acos(-1); RE calc(ll XMAX, ll YMAX, vi X, vi Y, vi R) { using P = Point; ll N = len(X); SHOW(N); vc> C(N); FOR(i, N) C[i] = Circle(P(X[i], Y[i]), R[i]); vc out(N); FOR(i, N) { if (XMAX + R[i] <= C[i].O.x) out[i] = 1; if (YMAX + R[i] <= C[i].O.y) out[i] = 1; if (C[i].O.x <= -R[i]) out[i] = 1; if (C[i].O.y <= -R[i]) out[i] = 1; } RE ANS = 0; vc> event; auto calc_c = [&](int i) -> void { event.clear(); if (out[i]) return; auto add = [&](Re s, Re t) -> void { FOR(k, -3, 4) { Re x = s + k * (2 * PI); Re y = t + k * (2 * PI); chmax(x, 0); chmin(y, PI + PI); if (x < y) { event.eb(x, 1), event.eb(y, -1); } } }; FOR(j, N) { if (j == i) continue; // 一致 if (C[i].O == C[j].O && C[i].r == C[j].r) { // 小さい方が境界に現れるとする if (j < i) return; continue; } Re d = (C[j].O - C[i].O).norm(); if (d >= C[i].r + C[j].r) continue; if (d <= C[i].r - C[j].r) { // j is inside i continue; } if (d <= C[j].r - C[i].r) { // i is inside j return; } Re r1 = C[i].r, r2 = C[j].r; Re cos_v = (r1 * r1 + d * d - r2 * r2) / (2 * r1 * d); chmax(cos_v, -1), chmin(cos_v, 1); Re t = acos(cos_v); Re dir = (C[j].O - C[i].O).angle(); add(dir - t, dir + t); } // bounding box { ll x = C[i].O.x; ll r = R[i]; if (XMAX < x + r) { ll d = XMAX - x; Re t = acos(Re(d) / r); add(0 - t, 0 + t); } } { ll y = C[i].O.y; ll r = R[i]; if (YMAX < y + r) { ll d = YMAX - y; Re t = acos(Re(d) / r); add(PI / 2 - t, PI / 2 + t); } } { ll x = C[i].O.x; ll r = R[i]; if (x < r) { ll d = x; Re t = acos(Re(d) / r); add(PI - t, PI + t); } } { ll y = C[i].O.y; ll r = R[i]; if (y < r) { ll d = y; Re t = acos(Re(d) / r); add(1.5 * PI - t, 1.5 * PI + t); } } auto add_range = [&](Re x, Re y) -> void { Re ans = 0; ans += R[i] * R[i] * (y - x) / 2; using PR = Point; PR A(C[i].O); PR B, C; B.x = A.x + cos(x) * R[i]; B.y = A.y + sin(x) * R[i]; C.x = A.x + cos(y) * R[i]; C.y = A.y + sin(y) * R[i]; ans += A.det(C) * 0.5; ans -= A.det(B) * 0.5; ANS += ans; }; Re x = 0; int now = 0; for (auto& [p, v] : event) { if (now == 0) add_range(x, p); now += v; x = p; } add_range(x, PI + PI); }; FOR(i, N) calc_c(i); // あとは線分を引きます // おお実は右と上だけでよい // 右 { event.clear(); auto add = [&](Re s, Re t) -> void { chmax(s, 0), chmin(t, YMAX); if (s < t) event.eb(s, 1), event.eb(t, -1); }; FOR(i, N) { if (out[i]) continue; ll x = C[i].O.x; ll y = C[i].O.y; ll r = R[i]; if (XMAX < x + r) { ll d = XMAX - x; Re h = sqrtl(r * r - d * d); add(y - h, y + h); } } auto add_range = [&](Re x, Re y) -> void { ANS += (y - x) * XMAX / 2; }; sort(all(event)); Re x = 0; int now = 0; for (auto& [p, v] : event) { if (now > 0) add_range(x, p); now += v; x = p; } } // 上 { event.clear(); auto add = [&](Re s, Re t) -> void { chmax(s, 0), chmin(t, XMAX); if (s < t) event.eb(s, 1), event.eb(t, -1); }; FOR(i, N) { if (out[i]) continue; ll x = C[i].O.x; ll y = C[i].O.y; ll r = R[i]; if (YMAX < y + r) { ll d = YMAX - y; Re h = sqrtl(r * r - d * d); add(x - h, x + h); } } auto add_range = [&](Re x, Re y) -> void { ANS += (y - x) * YMAX / 2; }; sort(all(event)); Re x = 0; int now = 0; for (auto& [p, v] : event) { if (now > 0) add_range(x, p); now += v; x = p; } } SHOW(ANS); return ANS; } void solve() { LL(XMAX, YMAX, N); vi X(N), Y(N), R(N), D(N); FOR(i, N) { read(X[i], Y[i], R[i]); CHAR(ch); D[i] = (ch == 'V' ? 1 : 2); } auto work = [&](int s) -> Re { vi XX, YY, RR; FOR(i, N) { if (!(s & D[i])) continue; XX.eb(X[i]); YY.eb(Y[i]); RR.eb(R[i]); } SHOW(XX, YY, RR); return calc(XMAX, YMAX, XX, YY, RR); }; vc A(4); FOR(s, 4) A[s] = work(s); A[1] -= A[3]; A[2] -= A[3]; A[0] = XMAX * YMAX - A[1] - A[2] - A[3]; RE ans = 0; ans += 1.0 * A[0]; ans += 0.5 * (A[1] + A[2]); // print(A); print(ans); } signed main() { solve(); } // END: main.cpp