Submission #1309182

#TimeUsernameProblemLanguageResultExecution timeMemory
1309182IUA_HasinConstruction Project 2 (JOI24_ho_t2)C++20
100 / 100
206 ms28316 KiB
#include <iostream> #include <vector> #include <queue> #include <algorithm> using namespace std; typedef long long ll; const ll INF = 2e18; // Dijkstra to find shortest paths from a source void dijkstra(int n, int start, const vector<vector<pair<int, int>>>& adj, vector<ll>& dist) { dist.assign(n + 1, INF); dist[start] = 0; priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<pair<ll, int>>> pq; pq.push({0, start}); while (!pq.empty()) { ll d = pq.top().first; int u = pq.top().second; pq.pop(); if (d > dist[u]) continue; for (auto& edge : adj[u]) { int v = edge.first; int w = edge.second; if (dist[u] + w < dist[v]) { dist[v] = dist[u] + w; pq.push({dist[v], v}); } } } } // Fenwick Tree for 2D range counting struct FenwickTree { int size; vector<int> tree; FenwickTree(int n) : size(n), tree(n + 1, 0) {} void add(int i, int val) { for (; i <= size; i += i & -i) tree[i] += val; } int query(int i) { int sum = 0; for (; i > 0; i -= i & -i) sum += tree[i]; return sum; } }; struct Point { ll x, y; }; struct Query { ll x_lim, y_lim, id; }; int main() { ios::sync_with_stdio(false); cin.tie(NULL); int N, M; cin >> N >> M; int S, T; ll L, K; cin >> S >> T >> L >> K; vector<vector<pair<int, int>>> adj(N + 1); for (int i = 0; i < M; ++i) { int u, v, c; cin >> u >> v >> c; adj[u].push_back({v, c}); adj[v].push_back({u, c}); } vector<ll> X(N + 1), Y(N + 1); dijkstra(N, S, adj, X); dijkstra(N, T, adj, Y); // If already happy, all pairs work if (X[T] <= K) { cout << (ll)N * (N - 1) / 2 << endl; return 0; } ll W = K - L; if (W < 0) { cout << 0 << endl; return 0; } ll C = 0; vector<ll> Y_vals; for (int i = 1; i <= N; ++i) { if (X[i] + Y[i] <= W) C++; Y_vals.push_back(Y[i]); } sort(Y_vals.begin(), Y_vals.end()); // Calculate |O|: ordered pairs (u, v) with u != v and X_u + Y_v <= W ll ordered_O = 0; for (int i = 1; i <= N; ++i) { ll limit = W - X[i]; ordered_O += upper_bound(Y_vals.begin(), Y_vals.end(), limit) - Y_vals.begin(); } ordered_O -= C; // Calculate |B|: pairs {u, v} satisfying both conditions using 2D range count vector<Point> points(N); vector<Query> queries(N); for (int i = 0; i < N; ++i) { points[i] = {X[i + 1], Y[i + 1]}; queries[i] = {W - Y[i + 1], W - X[i + 1], i + 1}; } sort(points.begin(), points.end(), [](Point a, Point b) { return a.x < b.x; }); sort(queries.begin(), queries.end(), [](Query a, Query b) { return a.x_lim < b.x_lim; }); vector<ll> coords = Y_vals; coords.erase(unique(coords.begin(), coords.end()), coords.end()); auto get_idx = [&](ll val) { return upper_bound(coords.begin(), coords.end(), val) - coords.begin(); }; FenwickTree ft(coords.size()); ll total_T = 0; int pt_idx = 0; for (int i = 0; i < N; ++i) { while (pt_idx < N && points[pt_idx].x <= queries[i].x_lim) { ft.add(get_idx(points[pt_idx].y), 1); pt_idx++; } total_T += ft.query(get_idx(queries[i].y_lim)); } ll unordered_B = (total_T - C) / 2; cout << ordered_O - unordered_B << endl; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...