#include "obstacles.h"
#include <bits/stdc++.h>
using namespace std;
#pragma GCC optimize("O5")
typedef long long ll;
typedef long double ld;
#define sp <<" "<<
#define endl "\n"
const int INF = 1e9+5;
struct maxtree {
int n, sz;
vector<int> tree;
maxtree(int l, int r, vector<int> &a) {
n = r+1;
sz = 2*n;
tree.resize(sz);
for (int i = 0; i < n; i++) {
tree[i + n] = a[i];
}
for (int i = n-1; i > 0; i--) {
tree[i] = max(tree[i<<1], tree[i<<1|1]);
}
}
int query(int l, int r) {
if (l == r) return tree[l + n];
l += n, r += n;
int res = -1;
while (l <= r) {
if (l & 1) {
res = max(res, tree[l]);
l++;
}
if (!(r & 1)) {
res = max(res, tree[r]);
r--;
}
l >>= 1, r >>= 1;
}
return res;
}
};
struct mintree {
int n, sz;
vector<int> tree;
mintree(int l, int r, vector<int> &a) {
n = r+1;
sz = 2*n;
tree.resize(sz);
for (int i = 0; i < n; i++) {
tree[i + n] = a[i];
}
for (int i = n-1; i > 0; i--) {
tree[i] = min(tree[i<<1], tree[i<<1|1]);
}
}
int query(int l, int r) {
if (l == r) return tree[l + n];
l += n, r += n;
int res = INF;
while (l <= r) {
if (l & 1) {
res = min(res, tree[l]);
l++;
}
if (!(r & 1)) {
res = min(res, tree[r]);
r--;
}
l >>= 1, r >>= 1;
}
return res;
}
};
int N, M;
vector<int> T, H;
maxtree *mxt;
mintree *mnt;
void initialize(vector<int> _T, vector<int> _H) {
N = _T.size(), M = _H.size();
T = _T, H = _H;
mxt = new maxtree(0, M-1, H);
mnt = new mintree(0, M-1, H);
return;
}
int cnt = 0;
int can_reach(int fir, int lo, int hi, int S, int D) {
{
int l = S, r = D;
while (r - l > 1) {
int m = (l+r) / 2;
if (fir > mxt->query(S, m)) {
l = m;
} else {
r = m;
}
}
S = l;
}
{
int l = S, r = D;
while (r - l > 1) {
int m = (l+r) / 2;
if (fir > mxt->query(m, D)) {
r = m;
} else {
l = m;
}
}
D = r;
}
int right = -1, left = M;
{
int l = -1, r = S+1;
while (r - l > 1) {
int m = (l+r) / 2;
if (lo > mnt->query(m, S)) {
l = m;
} else {
r = m;
}
}
right = l;
if (!(lo > mnt->query(right, S))) right = -1;
}
{
int l = D-1, r = M;
while (r - l > 1) {
int m = (l+r) / 2;
if (lo > mnt->query(D, m)) {
r = m;
} else {
l = m;
}
}
left = r;
if (!(lo > mnt->query(D, left))) left = M;
}
if (right == -1 or left == M) return 0;
if (!(fir > mxt->query(right, S))) return 0;
if (!(fir > mxt->query(D, left))) return 0;
if (mxt->query(right, left) < hi) return 1;
else return 2;
}
bool can_reach(int L, int R, int S, int D) {
cnt++;
if (S > D) swap(S, D);
int mx = mxt->query(S, D);
if (T[0] > mx) return true;
mx = T[0];
int mn = T[0];
for (int i = 1; i < N; i++) {
mn = min(mn, T[i]);
if (T[i] < mx) continue;
int res = can_reach(mx, mn, T[i], S, D);
if (res == 0) {
} else if (res == 1) {
return true;
} else if (res == 2) {
mx = max(mx, T[i]);
}
}
return false;
}
// subtask 3 3Q log N log M
// subtask 4 10N log N log M
// subtask 5 2d?! or binary search for the thing we need first
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |