Submission #1257698

#TimeUsernameProblemLanguageResultExecution timeMemory
1257698madamadam3Obstacles for a Llama (IOI25_obstacles)C++20
0 / 100
2095 ms13640 KiB
#include "obstacles.h"
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
using vi = vector<int>;
using vvi = vector<vi>;
using vl = vector<ll>;
using vvl = vector<vl>;
using pi = pair<int, int>;

#define FOR(i, a, b) for (int i = a; i < b; i++)
#define ROF(i, a, b) for (int i = a; i >= b; i--)
#define each(a, x) for (auto &a : x)
#define all(x) (x).begin(), (x).end()
#define bg(x) (x).begin()
#define en(x) (x).end()
#define rev(x) reverse(all(x))
#define sz(x) int((x).size())
#define srt(x) sort(all(x))
#define cnt(a, x) count(all(x), a)
#define trace(x) each(a, (x)) cout << a << " "
#define mp make_pair
#define pb push_back
#define lb lower_bound
#define ub upper_bound

struct DSU {
  int n; vi par, siz;

  DSU() {};
  DSU(int N) {
    n = N; par.resize(n); siz.assign(n, 1);
    iota(all(par), 0);
  }

  int find(int v) {
    if (par[v] == v) return v;
    return par[v] = find(par[v]);
  }

  void unite(int a, int b) {
    a = find(a); b = find(b);
    if (a != b) {
      if (siz[a] < siz[b]) swap(a, b);
      par[b] = a;
      siz[a] += siz[b];
    }
  }
};

struct SegTree {
  int n; vector<int> arr, st;

  SegTree() {};
  SegTree(int N, vector<int> &Arr) {
    n = N; arr = Arr; st.assign(4*n, INT_MIN);
    build(0, 0, n);
  }

  int build(int i, int l, int r) {
    if (l + 1 == r) return st[i] = arr[l];

    int m = l + (r - l) / 2;
    return st[i] = max(build(2*i+1, l, m), build(2*i+2, m, r));
  }

  int query(int i, int l, int r, int ql, int qr) {
    if (r <= ql || qr <= l) return INT_MIN;
    if (ql <= l && r <= qr) return st[i];

    int m = l + (r - l) / 2;
    return max(query(2*i+1, l, m, ql, qr), query(2*i+2, m, r, ql, qr));
  }

  int query(int l, int r) {
    return query(0, 0, n, l, r);
  }
};

int n, m;
SegTree rows, cols;
vi t, h, prefix_t;

void initialize(vi T, vi H) {
  t = T; h = H;
  n = sz(T), m = sz(H);
  rows = SegTree(n, T); cols = SegTree(m, H);

  prefix_t.assign(n+1, INT_MAX);
  for (int i = 0; i < n; i++) prefix_t[i+1] = min(prefix_t[i], t[i]);
  
  return;
}

int get_max_depth(int humidity) {
  int lo = 0, hi = n+1;
  while (lo < hi) {
    int mid = lo + (hi - lo + 1) / 2;

    if (prefix_t[mid] > humidity) {
      lo = mid;
    } else {
      hi = mid - 1;
    }
  }

  return lo;
}

bool can_reach(int L, int R, int S, int D) {
  if (S > D) swap(S, D);
  int a = S, b = S;

  while (a > 0 && t[0] > h[a - 1]) a--;
  while (b < m - 1 && t[0] > h[b+1]) b++;

  int c = D, d = D;
  while (c > 0 && t[0] > h[c - 1]) c--;
  while (d < m- 1 && t[0] > h[d+1]) d++;

  if (b >= D) return true;

  for (int i = a; i <= b; i++) {
    for (int j = c; j <= d; j++) {
      int k = get_max_depth(max(h[i], h[j]));
      if (rows.query(0, k) > cols.query(i, j+1)) return true;
    }
  }

  return false;
  
  int cl = a; for (int i = a; i <= b; i++) if (h[i] < h[cl]) cl = i;
  int cr = c; for (int i = c; i <= d; i++) if (h[i] < h[cr]) cr = i;
  int k = get_max_depth(max(h[cl], h[cr]));
  int br = rows.query(0, k);
  int bc = cols.query(cl, cr+1);

  return br > bc;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...