| # | Time | Username | Problem | Language | Result | Execution time | Memory |
|---|---|---|---|---|---|---|---|
| 1302283 | Valaki2 | Migrations (IOI25_migrations) | C++20 | 0 ms | 0 KiB |
#include "obstacles.h"
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
#define mp make_pair
#define pii pair<int, int>
#define fi first
#define se second
const int inf = 1e9 + 7;
const int maxn = 2e5;
int n, m;
vector<int> t, h;
vector<int> max_t, min_t;
vector<int> tree_max, tree_min;
void build(int v, int vl, int vr) {
if(vl == vr) {
tree_max[v] = tree_min[v] = h[vl];
} else {
int mid = (vl + vr) / 2;
build(2 * v, vl, mid);
build(2 * v + 1, mid + 1, vr);
tree_max[v] = max(tree_max[2 * v], tree_max[2 * v + 1]);
tree_min[v] = min(tree_min[2 * v], tree_min[2 * v + 1]);
}
}
pii query(int v, int vl, int vr, int ql, int qr) {
if(vl > qr || vr > ql) {
return mp(-1, inf);
}
if(vl == ql && vr == qr) {
return mp(tree_max[v], tree_min[v]);
}
int mid = (vl + vr) / 2;
pii q1 = query(2 * v, vl, mid, ql, min(qr, mid));
pii q2 = query(2 * v + 1, mid + 1, vr, max(ql, mid + 1), qr);
return mp(max(q1.fi, q2.fi), min(q1.se, q2.se));
}
int max_h(int l, int r) {
if(l > r) {
exit(1);
}
return query(1, 1, n, l, r).fi;
}
int min_h(int l, int r) {
if(l > r) {
exit(1);
}
return query(1, 1, n, l, r).se;
}
void initialize(vector<signed> T, vector<signed> H) {
n = T.size(), m = H.size();
t.assign(1 + n + 1, -1);
h.assign(1 + m + 1, inf);
for(int i = 1; i <= n; i++) {
t[i] = T[i - 1];
}
max_t = t;
min_t = t;
for(int i = 2; i <= n; i++) {
max_t[i] = max(max_t[i - 1], t[i]);
min_t[i] = min(min_t[i - 1], t[i]);
}
tree_max.assign(1 + 4 * m, -1);
tree_min.assign(1 + 4 * m, inf);
for(int i = 1; i <= m; i++) {
h[i] = H[i - 1];
}
build(1, 1, n);
}
int first_after(int idx, int maxisatleast) {
int l = idx - 1, r = m + 1;
while(l < r - 1) {
int mid = (l + r) / 2;
if(max_h(idx, mid) < maxisatleast) {
l = mid;
} else {
r = mid;
}
}
return r;
}
int last_before(int idx, int maxisatleast) {
int l = 0, r = idx + 1;
while(l < r - 1) {
int mid = (l + r) / 2;
if(max_h(mid, idx) < maxisatleast) {
r = mid;
} else {
l = mid;
}
}
return l;
}
pair<int, pii > find_box(int idx) {
for(int z = 1; z <= n; z++) {
if(t[z] > h[idx]) {
continue;
}
int l = last_before(idx, max_t[z]);
int r = first_after(idx, max_t[z]);
if(min_h(l, r) >= t[z]) {
return mp(z, mp(l, r));
}
}
return mp(n + 1, mp(0, m + 1));
}
bool can_reach(signed L, signed R, signed S, signed D) {
int a = S + 1, b = D + 1;
if(a > b) {
swap(a, b);
}
if(b <= a + 1) {
return true; // might have to remove !!
}
int c1 = find_box(a).se.se;
int c2 = find_box(b).se.fi;
if(c1 < b) {
return false;
}
if(c2 > a) {
return false;
}
return true;
}
