제출 #1192345

#제출 시각아이디문제언어결과실행 시간메모리
1192345TroySer벽 (IOI14_wall)C++20
100 / 100
732 ms214324 KiB
#include <bits/stdc++.h> #include "wall.h" using namespace std; using ll = int; const ll INF = 1e9; class SegTreeNode { private: ll l, r; SegTreeNode *leftChild, *rightChild; ll lowerBound, upperBound; public: SegTreeNode(ll l, ll r) { this->l = l, this->r = r; ll lowerBound = 0, upperBound = INF; if (l == r) { leftChild = nullptr; rightChild = nullptr; return; } ll M = (l + r) / 2; leftChild = new SegTreeNode(l, M); rightChild = new SegTreeNode(M + 1, r); } void fixBounds(ll lb, ll ub) { // this took me quite a while to get :') even looking at reflections, editorials, submissions, etc. // basically setting the "strictest" possible bounds for the wall upperBound = min(upperBound, ub); // if ub >= upperBound, i.e. if the "highest block" is higher than what we already have as "highest block", then idgaf lowerBound = min(lowerBound, upperBound); // lower bound must be at most upper bound lowerBound = max(lowerBound, lb); // if lb <= lowerBound, i.e. if the "lowest block" is lower than what we already have as "lowest", then idgaf upperBound = max(lowerBound, upperBound); // upper bound must be at least lower bound } void propagate() { if (leftChild != nullptr) { leftChild->fixBounds(lowerBound, upperBound); rightChild->fixBounds(lowerBound, upperBound); lowerBound = 0, upperBound = INF; } } ll query(ll i) { if (l == r) { return lowerBound; } ll M = (l + r) / 2; propagate(); if (i <= M) return leftChild->query(i); else return rightChild->query(i); } void addWall(ll ql, ll qr, ll newHeight) { if (l > qr || r < ql) return; if (ql <= l && r <= qr) { fixBounds(newHeight, INF); // only from newHeight to INF now propagate(); return; } ll M = (l + r) / 2; propagate(); leftChild->addWall(ql, qr, newHeight); rightChild->addWall(ql, qr, newHeight); } void removeWall(ll ql, ll qr, ll newHeight) { if (l > qr || r < ql) return; if (ql <= l && r <= qr) { fixBounds(0, newHeight); // only from 0 to newHeight now propagate(); return; } ll M = (l + r) / 2; propagate(); leftChild->removeWall(ql, qr, newHeight); rightChild->removeWall(ql, qr, newHeight); } }; void buildWall(int n, int k, int op[], int left[], int right[], int height[], int finalHeight[]){ SegTreeNode* st = new SegTreeNode(0, n - 1); for (ll i = 0; i < k; i++) { if (op[i] == 1) { st->addWall(left[i], right[i], height[i]); } else { st->removeWall(left[i], right[i], height[i]); } } for (ll i = 0; i < n; i++) { finalHeight[i] = st->query(i); } } // int main() { // int n = 10, k = 6; // int op[6] = {1, 2, 2, 1, 1, 2}; // int left[6] = {1, 4, 3, 0, 2, 6}; // int right[6] = {8, 9, 6, 5, 2, 7}; // int height[6] = {4, 1, 5, 3, 5, 0}; // int finalHeight[10]; // buildWall(n, k, op, left, right, height, finalHeight); // cout << "finalHeight: "; // for (auto l: finalHeight) { // cout << l << ", "; // } // cout << endl; // }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...