#include <bits/stdc++.h>
using namespace std;
const long long inf = 1e18;
const int N = 1e5 + 1;
int n, m, w, cost[N], meal2[N], cnt = 0, cur = 0;
long long dist[N];
set<pair<long long, int>> city[N];
vector<int> g[N];
priority_queue<pair<int, int>> q;
int rt[N], ls[20 * N], rs[20 * N], it[20 * N];
struct Edge {
int x, y, a, b, c;
bool operator<(const Edge &u) const { return a < u.a; }
} e[N];
struct Meal {
int l, r, id;
} meal[N];
bool cmp1(const Meal &x, const Meal &y) { return make_pair(x.r, x.l) < make_pair(y.r, y.l); }
bool cmp2(const Meal &x, const Meal &y) { return x.l < y.l; }
void upd(int i, int old, int l, int r, int p) {
it[i] = it[old] + 1;
if (l == r) return;
int mid = (l + r) >> 1;
if (p <= mid) {
rs[i] = rs[old];
upd(ls[i] = ++cnt, ls[old], l, mid, p);
} else {
ls[i] = ls[old];
upd(rs[i] = ++cnt, rs[old], mid + 1, r, p);
}
}
int query(int i, int l, int r, int u, int v) {
if (l > v || r < u) return 0;
if (u <= l && r <= v) return it[i];
int mid = (l + r) >> 1;
return query(ls[i], l, mid, u, v) + query(rs[i], mid + 1, r, u, v);
}
long long getval(int i) {
long long res = dist[i];
if (cur == 0) return res;
int p = upper_bound(meal2, meal2 + w, e[i].b) - meal2;
long long cnt = cur;
if (p) cnt -= query(rt[p - 1], 0, w - 1, 0, cur - 1);
assert(cnt >= 0);
return res + cnt * cost[e[i].y];
}
int findkth(int i, int j, int l, int r, int k) {
if (l == r) return l;
int mid = (l + r) >> 1, t = ls[j] - ls[i];
if (t >= k) return findkth(ls[i], ls[j], l, mid, k);
return findkth(rs[i], rs[j], mid + 1, r, k - t);
}
int getkth(int l, int r, int k) {
l = lower_bound(meal2, meal2 + w, l) - meal2;
r = upper_bound(meal2, meal2 + w, r) - meal2;
if (!r || r - l < k) return -1;
return findkth(l ? rt[l - 1] : 0, rt[r - 1], 0, w - 1, k);
}
bool calc(int i) {
int v = e[i].y;
auto it = city[v].find(make_pair(dist[i], i));
assert(it != city[v].end());
assert(it != city[v].begin());
long long dif = it->first - (prev(it))->first;
int k = (dif + cost[v] - 1) / cost[v];
int kth = getkth(e[prev(it)->second].b + 1, e[it->second].b, k);
if (kth == -1) return 0;
return g[kth].push_back(i), 1;
}
long long solve(int N, int M, int W, vector<int> T, vector<int> X, vector<int> Y, vector<int> A, vector<int> B, vector<int> C, vector<int> L, vector<int> R) {
n = N, m = M, w = W;
for (int i = 0; i < n; i++) cost[i] = T[i];
for (int i = 0; i < m; i++) e[i] = { X[i], Y[i], A[i], B[i], C[i] };
sort(e, e + m);
for (int i = 0; i < w; i++) meal[i] = { L[i], R[i], 0 };
sort(meal, meal + w, cmp1);
for (int i = 0; i < w; i++) meal[i].id = i;
sort(meal, meal + w, cmp2);
for (int i = 0; i < w; i++) {
upd(rt[i] = ++cnt, i ? rt[i - 1] : 0, 0, w - 1, meal[i].id);
meal2[i] = meal[i].l;
}
sort(meal, meal + w, cmp1);
memset(dist, -1, 8 * m);
city[0].insert(make_pair(0, m));
e[m].b = -1;
for (int i = 0; i < m; i++) {
while (cur < w && meal[cur].r <= e[i].a) {
for (int j : g[cur]) {
int v = e[j].b;
auto it = city[v].find(make_pair(dist[j], j));
if (it == city[v].end()) continue;
while (it != city[v].begin() && getval(prev(it)->second) >= getval(j)) city[v].erase(prev(it));
if (it != city[v].begin()) calc(j);
}
cur++;
}
while (q.size() && -q.top().first <= e[i].a) {
int j = q.top().second;
q.pop();
int v = e[j].y;
while (city[v].size() && getval(city[v].rbegin()->second) >= getval(j)) city[v].erase(--city[v].end());
city[v].insert(make_pair(dist[j], j));
if (city[v].size() > 1) calc(j);
}
int u = e[i].x;
if (city[u].empty()) continue;
dist[i] = getval(city[u].begin()->second) + e[i].c;
q.push(make_pair(-e[i].b, i));
}
long long res = inf;
for (int i = 0; i < m; i++)
if (e[i].y == n - 1 && dist[i] != -1) res = min(res, getval(i));
return res < inf ? res : -1;
}
# | 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... |