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;
#define pb push_back
#define ar array
#define all(x) x.begin(), x.end()
using i64 = long long;
const i64 inf = 1e15;
struct square{
i64 x1, x2, y1, y2;
square(i64 x1 = 0, i64 x2 = 0, i64 y1 = 0, i64 y2 = 0) : x1(x1), x2(x2), y1(y1), y2(y2) {}
square f(square q){
return square(max(x1, q.x1), min(x2, q.x2), max(y1, q.y1), min(y2, q.y2));
}
bool check(i64 x, i64 y){
return x1 <= x && x2 >= x && y1 <= y && y2 >= y;
}
};
struct SegTree{
vector <ar<i64,2>> T;
int n;
bool isMax;
SegTree(int n, bool isMax = false) : n(n), isMax(isMax) {
T.resize(n * 4 + 5, {inf, -1});
}
void upd(int v, int l, int r, int p, i64 x, int j){
if ( l == r ){
if ( T[v][0] > x ){
T[v] = {x, j};
}
return;
}
int m = (l + r) / 2;
if ( p <= m ) upd(v * 2, l, m, p, x, j);
else upd(v * 2 + 1, m + 1, r, p, x, j);
T[v] = min(T[v * 2], T[v * 2 + 1]);
}
void upd(int p, i64 x, int j){
if ( isMax ) x = -x;
upd(1, 0, n, p, x, j);
}
ar <i64,2> get(int v, int l, int r, int tl, int tr){
ar <i64,2> ret = {inf, -1};
if ( l > tr or r < tl ) return ret;
if ( tl <= l && tr >= r ){
return T[v];
}
int m = (l + r) / 2;
return min(get(v * 2, l, m, tl, tr), get(v * 2 + 1, m + 1, r, tl, tr));
}
int get(int l, int r){
return get(1, 0, n, l, r)[1];
}
};
long long find_shortcut(int n, std::vector<int> L, std::vector<int> d, int C){
vector <i64> x(n), A(n), B(n);
for ( int i = 1; i < n; i++ ){
x[i] = x[i - 1] + L[i - 1];
}
for ( int i = 0; i < n; i++ ){
A[i] = x[i] + d[i];
B[i] = x[i] - d[i];
}
vector <int> pa(n), pb(n);
for ( int i = 0; i < n; i++ ){
pa[i] = pb[i] = i;
}
sort(all(pa), [&](int &u, int &v){
return A[u] < A[v];
});
sort(all(pb), [&](int &u, int &v){
return B[u] < B[v];
});
auto P = B;
P.pb(-inf), P.pb(inf);
sort(all(P));
P.resize(unique(all(P)) - P.begin());
int m = P.size();
auto get = [&](i64 x){
return lower_bound(all(P), x) - P.begin();
};
auto ok = [&](i64 k){
i64 kk = k - C;
vector <ar<i64,3>> pt;
auto add = [&](int i, int j){
if ( i == -1 || j == -1 || i == j ) return;
if ( x[i] > x[j] ) swap(i, j);
pt.pb({x[i] + x[j], x[i] - x[j], kk - (d[i] + d[j])});
};
vector <ar<i64,2>> q(4, {inf, -1}), qq(4, {inf, -1});
auto upd = [&](int j){
vector <i64> t = {A[j], -A[j], B[j], -B[j]};
for ( int i = 0; i < 4; i++ ){
if ( q[i][0] > t[i] ){
if ( qq[i][0] > q[i][0] ){
qq[i] = q[i];
}
q[i] = {t[i], j};
}
}
};
int j = 0;
for ( auto &i: pa ){
while ( j < n && A[i] - k > B[pb[j]] ){
upd(pb[j]); j++;
}
for ( auto &[vv, j]: q ) add(i, j);
for ( auto &[v, j]: qq ) add(i, j);
}
//~ vector <SegTree> seg(4, SegTree(m));
//~ seg[1] = seg[3] = SegTree(m, 1);
//~ for ( int i = 0; i < n; i++ ){
//~ int u = get(A[i] - k) - 1, v = get(B[i]);
//~ vector <i64> q = {A[i], A[i], B[i], B[i]};
//~ for ( int j = 0; j < 4; j++ ){
//~ add(seg[j].get(0, u), i);
//~ seg[j].upd(v, q[j], i);
//~ }
//~ }
if ( pt.empty() ) return true;
auto [X, Y, d] = pt[0];
square t = square(X - d, X + d, Y - d, Y + d);
for ( int i = 1; i < (int)pt.size(); i++ ){
auto [x, y, d] = pt[i];
t = t.f(square(x - d, x + d, y - d, y + d));
}
if ( t.x1 > t.x2 || t.y1 > t.y2 ){ // area 0
return false;
}
bool flag = false;
int l = n, r = n - 1;
for ( int i = 0; i < n; i++ ){
while ( l > 0 && t.x1 - x[i] <= x[l - 1] ) l--;
while ( r >= 0 && t.x2 - x[i] < x[r] ) r--;
i64 p = -t.y2 + x[i];
int tl = l, tr = r + 1;
while ( tl + 1 < tr ){
int m = (tl + tr) / 2;
if ( p < x[m] ){
tr = m;
} else tl = m;
}
for ( auto j: {tl - 1, tl, tl + 1} ){
if ( l <= j && r >= j && j != i ){
flag |= t.check(x[i] + x[j], x[i] - x[j]);
}
}
}
//~ for ( int i = 0; i < n; i++ ){
//~ for ( int j = i + 1; j < n; j++ ){
//~ flag |= t.check(x[i] + x[j], x[i] - x[j]);
//~ }
//~ }
return flag;
};
i64 l = 0, r = 1e15;
while ( l < r ){
i64 m = (l + r) / 2;
if ( ok(m) ){
r = m;
} else l = m + 1;
}
return l;
}
Compilation message (stderr)
shortcut.cpp: In function 'long long int find_shortcut(int, std::vector<int>, std::vector<int>, int)':
shortcut.cpp:114:6: warning: unused variable 'm' [-Wunused-variable]
114 | int m = P.size();
| ^
shortcut.cpp:116:7: warning: variable 'get' set but not used [-Wunused-but-set-variable]
116 | auto get = [&](i64 x){
| ^~~
# | 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... |