백준 17975번: Strike Zone [C++] 작성일 2026-04-04 | In 백준 다이아몬드 V 문제 Strike Zone 풀이 10167번 금광 문제와 똑같은 풀이를 사용해서 해결할 수 있습니다. $y$좌표 두 개를 고정하여 그 안에 속하는 점들을 모두 금광 세그먼트 트리에 넣어 최대 부분 배열을 구하면 됩니다. 코드 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104#include <bits/stdc++.h> #ifndef ONLINE_JUDGE #define ASSERT(x) assert(x) #else #define ASSERT(_) ((void)0) #endif using namespace std; struct SegmentTree { struct Node { int sum, lmax, rmax, lrmax; void add(int v) { sum = lmax = rmax = lrmax += v; } }; Node merge(const Node& left, const Node& right) { Node ret; ret.sum = left.sum + right.sum; ret.lmax = max(left.lmax, left.sum + right.lmax); ret.rmax = max(right.rmax, left.rmax + right.sum); ret.lrmax = max({left.rmax + right.lmax, left.lrmax, right.lrmax}); return ret; } int n; vector<Node> t; SegmentTree(int _n) : n(1 << (int)ceil(log2(_n))), t(n << 1) {} void reset() { fill(t.begin(), t.end(), Node()); } void add(int i, int v) { t[i += n].add(v); while (i >>= 1) t[i] = merge(t[i << 1], t[i << 1 | 1]); } int getMaxSubArray() { return t[1].lrmax; } }; struct Point { int x, y; bool isStrike; }; Point points[2020]; vector<int> xValues; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n1; cin >> n1; for (int i = 0; i < n1; i++) { auto& [x, y, strike] = points[i]; strike = true; cin >> x >> y; xValues.push_back(x); } int n2; cin >> n2; int n = n1 + n2; for (int i = n1; i < n; i++) { auto& [x, y, strike] = points[i]; strike = false; cin >> x >> y; xValues.push_back(x); } int c1, c2; cin >> c1 >> c2; sort(xValues.begin(), xValues.end()); xValues.erase(unique(xValues.begin(), xValues.end()), xValues.end()); for (int i = 0; i < n; i++) { int& x = points[i].x; x = lower_bound(xValues.begin(), xValues.end(), x) - xValues.begin(); } sort(points, points + n, [&](const Point& a, const Point& b) { return a.y < b.y; }); SegmentTree segTree(xValues.size()); int answer = 0; for (int i = 0; i < n; i++) { if (i > 0 and points[i].y == points[i - 1].y) continue; segTree.reset(); for (int j = i; j < n; j++) { segTree.add(points[j].x, points[j].isStrike ? c1 : -c2); if (j == n - 1 or points[j].y != points[j + 1].y) answer = max(answer, segTree.getMaxSubArray()); } } cout << answer; return 0; }