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;
// macros
typedef long long ll;
typedef long double ld;
typedef pair<int, int> ii;
typedef pair<ll, ll> lll;
typedef tuple<int, int, int> iii;
typedef vector<int> vi;
typedef vector<ii> vii;
typedef vector<iii> viii;
typedef vector<ll> vll;
typedef vector<lll> vlll;
#define REP(a,b,c) for(int a=int(b); a<int(c); a++)
#define RE(a,c) REP(a,0,c)
#define RE1(a,c) REP(a,1,c+1)
#define REI(a,b,c) REP(a,b,c+1)
#define REV(a,b,c) for(int a=int(c-1); a>=int(b); a--)
#define FOR(a,b) for(auto& a : b)
#define all(a) a.begin(), a.end()
#define EPS 1e-9
#define pb push_back
#define popb pop_back
#define fi first
#define se second
#define sz size()
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
const ll INF = 1e18;
const int N = (1<<20);
ll n, c;
vll l, d;
struct MaxSeg {
    ll seg[N*2];
    void set(int i, ll v, int p=1, int l=0, int r=N-1) {
        if(i < l || i > r) return;
        if(l == r) {
            seg[p] = v;
            return;
        }
        int m=(l+r)/2;
        set(i,v,p*2,l,m);
        set(i,v,p*2+1,m+1,r);
        seg[p] = max(seg[p*2], seg[p*2+1]);
    }
    ll get(int i, int j, int p=1, int l=0, int r=N-1) {
        if(j < l || i > r) return -INF;
        if(i <= l && j >= r) return seg[p];
        int m=(l+r)/2;
        ll a=get(i,j,p*2,l,m);
        ll b=get(i,j,p*2+1,m+1,r);
        return max(a,b);
    }
} max1, max2;
struct MinSeg {
    MaxSeg maxSeg;
    void set(int i, ll v) {
        maxSeg.set(i,-v);
    }
    ll get(int i, int j) {
        return -maxSeg.get(i,j);
    }
} min1, min2;
bool possible(ll dist) {
    ll minSum=0, maxSum=INF, minDif=0, maxDif=INF;
    vll difValues;
    RE(i,n) difValues.pb(i);
    sort(all(difValues),[&](int i, int j) {
        return d[i]-l[i] > d[j]-l[j];
    });
    RE(i,n) {
        ll minValue = dist - d[i] - l[i];
        int lb=0, ub=n;
        while(lb != ub) {
            int mid=(lb+ub+1)/2;
            int j = difValues[mid-1];
            if(d[j]-l[j] > minValue) lb=mid;
            else ub=mid-1;
        }
        RE(x,lb) {
            int j = difValues[x];
            if(j >= i) continue;
            minDif = max(minDif, l[i] + d[i] - dist + c - l[j] + d[j]);
            maxDif = min(maxDif, l[i] - d[i] + dist - c - l[j] - d[j]);
            minSum = max(minSum, l[i] + d[i] - dist + c + l[j] + d[j]);
            maxSum = min(maxSum, l[i] - d[i] + dist - c + l[j] - d[j]);
        }
    }
    // original function
    /*
    RE(i,n) RE(j,i) {
        ll curDist = d[i] + l[i] + d[j] - l[j];
        if(curDist <= dist) continue;
        minDif = max(minDif, l[i] + d[i] - dist + c - l[j] + d[j]);
        maxDif = min(maxDif, l[i] - d[i] + dist - c - l[j] - d[j]);
        minSum = max(minSum, l[i] + d[i] - dist + c + l[j] + d[j]);
        maxSum = min(maxSum, l[i] - d[i] + dist - c + l[j] - d[j]);
    }
    */
    REP(i,1,n) {
        ll curDif, curSum;
        int j1 = 0, j2 = 0;
        int lb=0, ub=i-1;
        while(lb != ub) {
            int mid=(lb+ub)/2;
            curDif = l[i]-l[mid];
            if(curDif > maxDif) lb=mid+1;
            else ub=mid;
        }
        j1 = lb;
        lb=0, ub=i-1;
        while(lb != ub) {
            int mid=(lb+ub)/2;
            curSum = l[i]+l[mid];
            if(curSum < minSum) lb=mid+1;
            else ub=mid;
        }
        j2 = lb;
        curDif = l[i]-l[j1];
        curSum = l[i]+l[j1];
        if(minDif <= curDif && curDif <= maxDif && minSum <= curSum && curSum <= maxSum)
            return true;
        curDif = l[i]-l[j2];
        curSum = l[i]+l[j2];
        if(minDif <= curDif && curDif <= maxDif && minSum <= curSum && curSum <= maxSum)
            return true;
    }
    return false;
}
ll find_shortcut(int n_, vi l_, vi d_, int c_) {
    n = n_; c=c_;
    l.pb(0);
    FOR(i,l_)
        l.pb(i);
    FOR(i,d_) d.pb(i);
    REP(i,1,n) l[i]+=l[i-1];
    ll lb=0, ub=INF;
    while(lb != ub) {
        ll mid=(lb+ub)/2;
        if(possible(mid)) ub=mid;
        else lb=mid+1;
    }
    return lb;
}
| # | 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... |