# | Time | Username | Problem | Language | Result | Execution time | Memory |
---|---|---|---|---|---|---|---|
1240167 | coderg | Wall (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, 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 newlevel=node<<1;
ll val = tree[node].lazy_min;
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;
}
}
// for op 2 , to limit the maximum height
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,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);
}
// for op 1 , to set a minimum height
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,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);
}
// to build final heights
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,newlevel=node<<1;;
build_final(newlevel+1, l, m, finalHeight);
build_final(newlevel+2, m+1, r, finalHeight);
}
void buildWall(ll n, ll k, ll op[], ll left[], ll right[], ll height[], ll finalHeight[]) {
for (ll i = 0; i < 4*MAXN; i++) {
tree[i] = Node();
}
for (ll i = 0; i < k; i++) {
if (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(0, 0, n-1, finalHeight);
}