제출 #1255877

#제출 시각아이디문제언어결과실행 시간메모리
1255877nicolo_010장애물 (IOI25_obstacles)C++20
44 / 100
2096 ms68452 KiB
#pragma GCC optimize("Ofast")
#include "obstacles.h"
#include <bits/stdc++.h>
using namespace std;
template <typename T>
using v = vector<T>;
using ll = long long;
using pii = pair<int, int>;
#define rep(i, k, n) for (int i = k; i < n; i++)
#define cout if(0) cout

struct SegTree {
  v<int> tree;
  v<int> mx;

  SegTree() {}

  SegTree(int n) {
    tree.assign(4*n, 1e9);
    mx.assign(4*n, 0);
  }

  void build(int p, int l, int r, int i, int x) {
    if (l > i || r < i) return;
    if (l == r && r == i) {
      tree[p] = x;
      mx[p] = x;
    }
    else {
      build(2*p, l, (l+r)/2, i, x);
      build(2*p+1, (l+r)/2+1, r, i, x);
      tree[p] = min(tree[2*p], tree[2*p+1]);
      mx[p] = max(mx[2*p], mx[2*p+1]);
    }
  }

  int query(int p, int l, int r, int i, int j) {
    if (l > j || r < i) return 1e9;
    if (i <= l && r <= j) return tree[p];
    else {
      int i1 = query(2*p, l, (l+r)/2, i, j);
      int i2 = query(2*p+1, (l+r)/2+1, r, i, j);
      return min(i1, i2);
    }
  }

  int maxx(int p, int l, int r, int i, int j) {
    if (l > j || r < i) return 0;
    if (i <= l && r <= j) return mx[p];
    else {
      int i1 = maxx(2*p, l, (l+r)/2, i, j);
      int i2 = maxx(2*p+1, (l+r)/2+1, r, i, j);
      return max(i1, i2);
    }
  }
  
};

int N, M;
SegTree stT, stH;
v<int> t, h;
v<int> sig;
v<v<int>> liftleft;
v<v<int>> liftright;
void initialize(std::vector<int> T, std::vector<int> H) {
  t = T;
  h = H;
  N = T.size();
  M = H.size();
  //rep(i, 0, N) {rep(j, 0, M) {if (T[i] > H[j]) cout << 1 << " ";else cout << 0 << " ";}cout << endl;}
  stT = SegTree(N);
  stH = SegTree(M);
  rep(i, 0, N) {
    stT.build(1, 0, N-1, i, T[i]);
  }
  rep(i, 0, M) {
    stH.build(1, 0, M-1, i, H[i]);
  }
  liftleft.assign(M, v<int>(20, 1e9));
  liftright.assign(M, v<int>(20, 1e9));
  rep(i, 0, M) {
    if (i > 0) liftleft[i][0] = H[i-1];
    if (i < M-1) liftright[i][0] = H[i+1];
  }
  rep(j, 1, 20) {
    rep(i, 0, M) {
      if (i - (1 << (j-1)) > 0) liftleft[i][j] = max(liftleft[i - (1 << (j-1))][j-1], liftleft[i][j-1]);
      if (i + (1 << (j-1)) < M) {
        if (j == 2 && i == 1) {
          cout << liftright[i+(1<<(j-1))][j-1] << " " << liftright[i][j-1] << endl;
        }
        liftright[i][j] = max(liftright[i + (1 << (j-1))][j-1], liftright[i][j-1]);
      }
    }
  }
  stack<int> s;
  stack<int> idx;
  sig.assign(N, -1);
  rep(i, 0, N) {
    while (s.size() && T[i] > s.top()) {
      sig[idx.top()] = i;
      idx.pop();
      s.pop();
    }
    s.push(T[i]);
    idx.push(i);
  }
  return;
}

bool salto_valido(int row1, int row2, int l, int r) {
  int mnH = stH.query(1, 0, M-1, l, r);
  int mnT = stT.query(1, 0, N-1, row1, row2);
  if (mnT > mnH) return true;
  else return false;
}

pair<int, int> find_range(int S) {
  int row = 0;
  int l, r;
  l = r = S;
  for (int i = 19; i >= 0; i--) {
    if (liftleft[l][i] < t[row]) {
      l -= (1 << i);
    }
  }
  for (int i = 19; i >= 0; i--) {
    if (liftright[r][i] < t[row]) {
      r += (1 << i);
    }
  }
  while (sig[row] != -1 && salto_valido(row, sig[row], l, r)) {
    row = sig[row];
    cout << l << " "<< r << endl;
    for (int i = 19; i >= 0; i--) {
      if (liftleft[l][i] < t[row]) {
        l -= (1 << i);
      }
    }
    for (int i = 19; i >= 0; i--) {
      cout << r << " " << i << " " << liftright[r][i] << endl;
      if (liftright[r][i] < t[row]) {
        r += (1 << i);
        cout << i << endl;
      }
    }
  }
  return {l, r};
}

bool can_reach(int L, int R, int S, int D) {
  int l1, r1;
  auto aux = find_range(S);
  l1 = aux.first, r1 = aux.second;
  int l2, r2;
  aux = find_range(D);
  l2 = aux.first, r2 = aux.second;
  //cout << l1 << " "<< r1 << " " << l2 << " "<< r2 << endl;
  if (l1 == l2 && r1 == r2) return true;
  else return false;
}
#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...