This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include "shortcut.h"
#include <bits/stdc++.h>
using namespace std;
using ll=long long;
using pll=pair<ll,ll>;
#define all(x) x.begin(), x.end()
#define x first
#define y second
const int maxn = int(1e6) + 10;
int n;
int C;
ll pos[maxn];
ll d[maxn];
pll rpdr[maxn];
pll lmdl[maxn];
const ll inf = 1ll<<60;
struct BoundSys {
pll mx, smx;
void init(){ mx = smx = {-inf, -1}; }
BoundSys(){ init(); }
void upd(ll val, ll idx) {
pll t(val, idx);
if(mx < t) smx = mx, mx = t;
else if(smx < t) smx = t;
}
ll get_max(ll idx) {
if(mx.y != -1 && mx.y != idx) return mx.x;
else if(smx.y != -1) return smx.x;
else return -inf;
}
};
struct Gug {
BoundSys bl, br;
ll rL, rR;
Gug(){ bl.init(); br.init(); rL = -inf; rR = +inf; }
void Add(ll lv, ll rv, ll i) { bl.upd(lv, i); br.upd(-rv, i); }
void upd(ll lv, ll rv, ll i) {
rL = max(rL, bl.get_max(i) + lv);
rR = min(rR, -br.get_max(i) + rv);
}
};
bool f(ll X) {
int lst = n;
Gug ipj, imj;
auto Add = [&](int r) {
ipj.Add(pos[r] + d[r], pos[r]-d[r], r);
imj.Add(d[r] - pos[r], -d[r]-pos[r], r);
};
auto Upd = [&](int l) {
ipj.upd(pos[l] + d[l] + C-X, pos[l] - d[l] + X-C, l);
imj.upd(pos[l] + d[l] + C-X, pos[l] - d[l] + X-C, l);
};
for(int i=n-1; 0<=i; --i) {
while(lst-1 >= 0 && rpdr[lst-1].x > lmdl[i].x + X) {
--lst;
Add(rpdr[lst].y);
}
Upd(lmdl[i].y);
}
int jminp = 0, jminm = 0;
int jmaxp = n-1, jmaxm = n-1;
while(jminp < n && pos[jminp] < ipj.rL-pos[0]) ++jminp;
while(jmaxm >= 0 && pos[jmaxm] > pos[0]-imj.rL) --jmaxm;
for(int i=0; i<n; ++i) {
ll pi = pos[i];
while(jminp >= 1 && pos[jminp-1] >= ipj.rL-pi) --jminp;
while(jminm < n && pos[jminm] < pi-imj.rR) ++jminm;
while(jmaxp >= 0 && pos[jmaxp] > ipj.rR-pi) --jmaxp;
while(jmaxm+1 < n && pos[jmaxm+1] <= pi-imj.rL) ++jmaxm;
if(max(jminp, jminm) <= min(jmaxp, jmaxm)) {
return 1;
}
}
return 0;
}
long long find_shortcut(int _n, std::vector<int> l, std::vector<int> _d, int c)
{
n = _n;
C = c;
copy(all(_d), d);
for(int i=1; i<n; ++i) pos[i] = pos[i-1] + l[i-1];
for(int i=0; i<n; ++i) {
rpdr[i] = {pos[i] + d[i], i};
lmdl[i] = {pos[i] - d[i], i};
}
sort(rpdr, rpdr+n);
sort(lmdl, lmdl+n);
ll L = 0, R = 2e16;
ll pmx = 0;
for(int i=0; i<n; ++i) {
if(i)
L = max(L, d[i] + pmx);
pmx = max(pmx, d[i]);
}
while(L+1 < R) {
ll mid = (L+R) / 2;
if(f(mid)) R = mid;
else L = mid;
}
return R;
}
# | 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... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |