李超线段树

//最小
#include <bits/stdc++.h>
using i64 = long long;
struct Line {
i64 m, b;
Line(i64 _m = 0, i64 _b = LLONG_MAX) : m(_m), b(_b) {}
i64 eval(i64 x) const { return m * x + b; }
};
struct Node {
Line ln;
Node *lch, *rch;
Node(const Line& _ln) : ln(_ln), lch(nullptr), rch(nullptr) {}
};
struct LiChao {
i64 L, R;
Node* root;
LiChao(i64 _L, i64 _R) : L(_L), R(_R), root(nullptr) {}
void add_line(i64 m, i64 b) {
insert(root, L, R, Line(m, b));
}
i64 query(i64 x) const {
return query_min(root, L, R, x);
}
void insert(Node*& nd, i64 l, i64 r, Line ln) {
if (!nd) {
nd = new Node(ln);
return;
}
i64 mid = (l + r) >> 1;
bool left = ln.eval(l) < nd->ln.eval(l);
bool mid_ = ln.eval(mid) < nd->ln.eval(mid);
if (mid_)
std::swap(ln, nd->ln);
if (l == r)
return;
if (left != mid_)
insert(nd->lch, l, mid, ln);
else
insert(nd->rch, mid + 1, r, ln);
}
i64 query_min(Node* nd, i64 l, i64 r, i64 x) const {
if (!nd) return LLONG_MAX;
i64 res = nd->ln.eval(x);
if (l == r) return res;
i64 mid = (l + r) >> 1;
if (x <= mid)
return std::min(res, query_min(nd->lch, l, mid, x));
else
return std::min(res, query_min(nd->rch, mid + 1, r, x));
}
};
void solve() {
int n, m;
std::cin >> n >> m;
std::vector<std::tuple<int, int, i64, int>> edges(m);
std::vector<std::vector<std::pair<int, i64>>> adj(n);
std::vector<std::vector<std::pair<int, i64>>> radj(n);
for (int i = 0; i < m; ++ i) {
int u, v, w;
i64 t;
std::cin >> u >> v >> t >> w;
-- u, -- v;
adj[u].emplace_back(v, t);
radj[v].emplace_back(u, t);
edges[i] = {u, v, t, w};
}
const i64 inf = 1e18;
auto dijkstra = [&](std::vector<i64> & dist, std::vector<std::vector<std::pair<int, i64>>> & adj, int s) -> void {
using PII = std::pair<i64, int>;
std::priority_queue<PII, std::vector<PII>, std::greater<PII>> heap;
std::fill(dist.begin(), dist.end(), inf);
dist[s] = 0;
heap.emplace(dist[s], s);
while (heap.size()) {
auto [d, u] = heap.top(); heap.pop();
if (d != dist[u]) {
continue;
}
for (auto & [v, w] : adj[u]) {
if (dist[v] > dist[u] + w) {
dist[v] = dist[u] + w;
heap.emplace(dist[v], v);
}
}
}
};
std::vector<i64> d1(n), dn(n);
dijkstra(d1, adj, 0);
dijkstra(dn, radj, n - 1);
LiChao tr(1, 1e9);
for (auto & [u, v, t, w] : edges) {
i64 d = d1[u] + dn[v];
if (d < inf) {
tr.add_line(-w, d + t);
}
}
int q;
std::cin >> q;
while (q -- ) {
i64 k;
std::cin >> k;
std::cout << tr.query(k) << "\n";
}
}
int main() {
std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
int t = 1;
std::cin >> t;
while (t -- ) {
solve();
}
return 0;
}
浙公网安备 33010602011771号