# | Time | Username | Problem | Language | Result | Execution time | Memory |
---|---|---|---|---|---|---|---|
1240171 | coderg | 벽 (IOI14_wall) | C++20 | 0 ms | 0 KiB |
#include "wall.h"
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll MAXN = 2000001;
const ll INF = 1e9;
struct Node {
ll min_val, max_val, lazy_min, lazy_max;
Node() {
min_val = 0;
max_val = INF;
lazy_min = 0;
lazy_max = INF;
}
};
Node tree[4*MAXN];
void push_lazy(ll node, ll l, ll r) {
if (l == r) return;
// propagate max operations
if (tree[node].lazy_max != INF) {
ll val = tree[node].lazy_max;
ll newlevel = node<<1;
for (ll child = newlevel+1; child <= newlevel+2; child++) {
tree[child].max_val = min(tree[child].max_val, val);
tree[child].min_val = min(tree[child].min_val, val);
tree[child].lazy_max = min(tree[child].lazy_max, val);
tree[child].lazy_min = min(tree[child].lazy_min, val);
}
tree[node].lazy_max = INF;
}
// propagate min operations
if (tree[node].lazy_min != 0) {
ll val = tree[node].lazy_min;
ll newlevel = node<<1;
for (ll child = newlevel+1; child <= newlevel+2; child++) {
tree[child].max_val = max(tree[child].max_val, val);
tree[child].min_val = max(tree[child].min_val, val);
tree[child].lazy_max = max(tree[child].lazy_max, val);
tree[child].lazy_min = max(tree[child].lazy_min, val);
}
tree[node].lazy_min = 0;
}
}
void update_max(ll node, ll l, ll r, ll a, ll b, ll val) {
push_lazy(node, l, r);
if (b < l || a > r) return;
if (a <= l && r <= b) {
tree[node].max_val = min(tree[node].max_val, val);
tree[node].min_val = min(tree[node].min_val, val);
tree[node].lazy_max = min(tree[node].lazy_max, val);
tree[node].lazy_min = min(tree[node].lazy_min, val);
return;
}
ll m = (l + r) / 2;
ll newlevel = node<<1;
update_max(newlevel+1, l, m, a, b, val);
update_max(newlevel+2, m+1, r, a, b, val);
tree[node].min_val = min(tree[newlevel+1].min_val, tree[newlevel+2].min_val);
tree[node].max_val = max(tree[newlevel+1].max_val, tree[newlevel+2].max_val);
}
void update_min(ll node, ll l, ll r, ll a, ll b, ll val) {
push_lazy(node, l, r);
if (b < l || a > r) return;
if (a <= l && r <= b) {
tree[node].max_val = max(tree[node].max_val, val);
tree[node].min_val = max(tree[node].min_val, val);
tree[node].lazy_max = max(tree[node].lazy_max, val);
tree[node].lazy_min = max(tree[node].lazy_min, val);
return;
}
ll m = (l + r) / 2;
ll newlevel = node<<1;
update_min(newlevel+1, l, m, a, b, val);
update_min(newlevel+2, m+1, r, a, b, val);
tree[node].min_val = min(tree[newlevel+1].min_val, tree[newlevel+2].min_val);
tree[node].max_val = max(tree[newlevel+1].max_val, tree[newlevel+2].max_val);
}
void build_final(ll node, ll l, ll r, ll finalHeight[]) {
push_lazy(node, l, r);
if (l == r) {
finalHeight[l] = tree[node].min_val;
return;
}
ll m = (l + r) / 2;
ll newlevel = node<<1;
build_final(newlevel+1, l, m, finalHeight);
build_final(newlevel+2, m+1, r, finalHeight);
}
void buildWall(int n, int k, int op[], int left[], int right[], int height[], int finalHeight[]) {
for (ll i = 0; i < 4*MAXN; i++) {
tree[i] = Node();
}
for (ll i = 0; i < k; i++) {
op[i] = op[i];
left[i] = left[i];
right[i] = right[i];
height[i] = height[i];
}
// Process operations
for (ll i = 0; i < k; i++) {
if (ll_op[i] == 1) { // Add blocks (min height)
update_min(0, 0, n-1, left[i],right[i], height[i]);
} else { // Remove blocks (max height)
update_max(0, 0, n-1, left[i], right[i], height[i]);
}
}
// Build final heights
ll* finalHeight = new ll[n];
build_final(0, 0, n-1, finalHeight);
}