Submission #1014823

#TimeUsernameProblemLanguageResultExecution timeMemory
1014823MilosMilutinovicShortcut (IOI16_shortcut)C++14
100 / 100
1672 ms71764 KiB
#include "shortcut.h"
#include <bits/stdc++.h>

using namespace std;

const int MAX = 1000005;

const long long inf = (long long) 1e18;

int n, c, d[MAX], order[2][MAX];
long long x[MAX], val[MAX][2];

bool Check(long long diam) {
  long long xl = -inf, xr = inf;
  long long yl = -inf, yr = inf;
  vector<pair<int, int>> mn(2, {-1, -1});
  vector<pair<int, int>> mx(2, {-1, -1});
  auto Update = [&](int i) {
    if (mn[0].first == -1 || val[i][0] < val[mn[0].first][0]) {
      swap(mn[0].first, mn[0].second);
      mn[0].first = i;
    } else if (mn[0].second == -1 || val[i][0] < val[mn[0].second][0]) {
      mn[0].second = i;
    }

    if (mn[1].first == -1 || val[i][1] < val[mn[1].first][1]) {
      swap(mn[1].first, mn[1].second);
      mn[1].first = i;
    } else if (mn[1].second == -1 || val[i][1] < val[mn[1].second][1]) {
      mn[1].second = i;
    }

    if (mx[0].first == -1 || val[i][0] > val[mx[0].first][0]) {
      swap(mx[0].first, mx[0].second);
      mx[0].first = i;
    } else if (mx[0].second == -1 || val[i][0] > val[mx[0].second][0]) {
      mx[0].second = i;
    }

    if (mx[1].first == -1 || val[i][1] > val[mx[1].first][1]) {
      swap(mx[1].first, mx[1].second);
      mx[1].first = i;
    } else if (mx[1].second == -1 || val[i][1] > val[mx[1].second][1]) {
      mx[1].second = i;
    }
  };
  int ptr = 0;
  for (int _i = 0; _i < n; _i++) {
    int i = order[0][_i];
    while (ptr < n && val[i][0] - val[order[1][ptr]][1] > diam) {
      Update(order[1][ptr]);
      ptr += 1;
    }
    
    if (mx[0].first != i && mx[0].first != -1) {
      xl = max(xl, val[i][0] - diam + c + val[mx[0].first][0]);
    } else if (mx[0].second != -1) {
      xl = max(xl, val[i][0] - diam + c + val[mx[0].second][0]);
    }

    if (mn[1].first != i && mn[1].first != -1) {
      xr = min(xr, val[i][1] + diam - c + val[mn[1].first][1]);
    } else if (mn[1].second != -1) {
      xr = min(xr, val[i][1] + diam - c + val[mn[1].second][1]);
    }

    if (mn[1].first != i && mn[1].first != -1) {
      yl = max(yl, val[i][0] - diam + c - val[mn[1].first][1]);
    } else if (mn[1].second != -1) {
      yl = max(yl, val[i][0] - diam + c - val[mn[1].second][1]);
    }

    if (mx[0].first != i && mx[0].first != -1) {
      yr = min(yr, val[i][1] + diam - c - val[mx[0].first][0]);
    } else if (mx[0].second != -1) {
      yr = min(yr, val[i][1] + diam - c - val[mx[0].second][0]);
    }
  }
  int plx = n, prx = n - 1, ply = 0, pry = -1;
  for (int i = 0; i < n; i++) {
    while (plx > 0 && x[i] + x[plx - 1] >= xl) {
      plx--;
    }
    while (prx >= 0 && x[i] + x[prx] > xr) {
      prx--;
    }
    while (ply < n && x[ply] - x[i] < yl) {
      ply++;
    }
    while (pry + 1 < n && x[pry + 1] - x[i] <= yr) {
      pry++;
    }
    int L = max({i + 1, plx, ply}), R = min(prx, pry);
    if (L <= R) {
      return true;
    }
  }
  return false;
}

long long find_shortcut(int n, vector<int> l, vector<int> d, int c) {
  ::n = n; ::c = c;
  for (int i = 1; i < n; i++) {
    x[i] = x[i - 1] + l[i - 1];
  }
  for (int i = 0; i < n; i++) {
    ::d[i] = d[i];
  }
  for (int i = 0; i < n; i++) {
    val[i][0] = x[i] + d[i];
    val[i][1] = x[i] - d[i];
  }
  for (int t = 0; t < 2; t++) {
    for (int i = 0; i < n; i++) {
      order[t][i] = i;
    }
    sort(order[t], order[t] + n, [&](int i, int j) {
      return (t == 0 ? val[i][0] < val[j][0] : val[i][1] < val[j][1]);
    });
  }  
  long long low = 0, high = inf / 50, ans = 0;
  while (low <= high) {
    long long mid = (low + high) >> 1;
    if (Check(mid)) {
      ans = mid;
      high = mid - 1;
    } else {
      low = mid + 1;
    }
  }
  return ans;
}
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...