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 "overtaking.h"
#include <bits/stdc++.h>
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
using namespace std;
typedef long long ll;
typedef long double ld;
const ll inf = 4e18 + 10;
struct Line{
ll a, b;
ll id;
};
bool cmp(Line l1, Line l2, ll x) {
ll t1 = (x-l1.a) / l1.b, t2 = (x-l2.a) / l2.b;
if (t1 == t2) return ((x-l1.a)-t1*l1.b) * l2.b < ((x-l2.a)-t2*l2.b) * l1.b;
return t1 < t2;
}
struct Node{
ll l, r;
Line line;
};
struct LiChaoTree{
vector<Node> tree;
void init() {
tree.clear();
tree.push_back({-1, -1, {-inf, 1, -1}});
}
void update(ll node, ll s, ll e, Line p) {
Line lo = tree[node].line;
Line hi = p;
if (cmp(hi, lo, s)) swap(lo, hi);
if (!cmp(hi, lo, e)) {
tree[node].line = lo;
return;
}
ll mid = (s + e) / 2;
if (!cmp(hi, lo, mid)) {
tree[node].line = lo;
if (tree[node].r == -1) {
tree[node].r = tree.size();
tree.push_back({-1, -1, {-inf, 1, -1}});
}
update(tree[node].r, mid+1, e, hi);
}
else {
tree[node].line = hi;
if (tree[node].l == -1) {
tree[node].l = tree.size();
tree.push_back({-1, -1, {-inf, 1, -1}});
}
update(tree[node].l, s, mid, lo);
}
}
Line query(ll node, ll s, ll e, ll x) {
if (node == -1) return {-inf, 1, -1};
if (s == e) return tree[node].line;
ll mid = (s + e) / 2;
if (x <= mid) {
Line t = query(tree[node].l, s, mid, x);
if (cmp(t, tree[node].line, x)) return t;
return tree[node].line;
}
Line t = query(tree[node].r, mid+1, e, x);
if (cmp(t, tree[node].line, x)) return t;
return tree[node].line;
}
};
LiChaoTree seg;
LiChaoTree seg2[1010];
vector<ll> t1;
int N, M;
ll L, X;
vector<ll> T, W, S;
ll arr[1010][1010];
ll st[1010][1010];
void init(int _L, int _N, vector<ll> _T, vector<int> _W, int _X, int _M, vector<int> _S)
{
L = _L;
X = _X;
M = _M;
for (int i=0; i<M; i++) {
S.push_back(_S[i]);
}
for (int i=0; i<_N; i++) {
if (_W[i] > X) {
T.push_back(_T[i]);
W.push_back(_W[i]);
N ++;
}
}
for (int i=0; i<N; i++) {
arr[0][i] = T[i];
}
for (int i=1; i<M; i++) {
vector<tuple<ll,ll,ll>> id(N);
for (ll j=0; j<N; j++) {
id[j] = {arr[i-1][j], W[j], j};
}
sort(id.begin(), id.end());
ll mx = 0;
for (auto &[t1, t2, j] : id) {
arr[i][j] = max(mx, arr[i-1][j] + W[j] * (S[i] - S[i-1]));
mx = max(mx, arr[i][j]);
}
}
for (int i=M-1; i>=0; i--) {
vector<pair<ll,ll>> id(N);
for (ll j=0; j<N; j++) {
id[j] = {arr[i][j], j};
}
sort(id.begin(), id.end());
seg.init();
for (auto &[_, j] : id) {
if (j == id[0].second) {
st[i][j] = arr[i][j] + (L - S[i]) * X;
}
else {
ll cross = seg.query(0, 0, inf, arr[i][j]).id;
assert(cross != -1);
ll pos = S[i] + (arr[i][j] - arr[i][cross] + W[cross] - X - 1) / (W[cross] - X);
if (pos > L) {
st[i][j] = arr[i][j] + (L - S[i]) * X;
}
else {
ll idx = lower_bound(S.begin(), S.end(), pos) - S.begin();
st[i][j] = st[idx][cross];
}
}
seg.update(0, 0, inf, {arr[i][j], W[j] - X, j});
}
}
vector<int> id(N);
iota(id.begin(), id.end(), 0);
sort(id.begin(), id.end(), [&] (int &u, int &v) { return T[u] < T[v]; });
for (int i=0; i<=N; i++) {
seg2[i].init();
for (int j=0; j<i; j++) {
seg2[i].update(0, 0, inf, {T[id[j]], W[id[j]] - X, id[j]});
}
}
t1 = T;
sort(t1.begin(), t1.end());
return;
}
long long arrival_time(long long Y)
{
ll idx = lower_bound(t1.begin(), t1.end(), Y) - t1.begin();
if (idx == 0) return Y + X * L;
ll cross = seg2[idx].query(0, 0, inf, Y).id;
assert(cross != -1);
ll pos = (Y - T[cross] + W[cross] - X - 1) / (W[cross] - X);
if (pos > L) return Y + X * L;
ll idx2 = lower_bound(S.begin(), S.end(), pos) - S.begin();
assert(st[idx2][cross] >= Y);
return st[idx2][cross];
}
# | 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... |