Submission #777625

#TimeUsernameProblemLanguageResultExecution timeMemory
777625tch1cherinTwo Currencies (JOI23_currencies)C++17
100 / 100
570 ms42136 KiB
#pragma GCC optimize("Ofast,unroll-loops") #pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt,fma") #include <bits/stdc++.h> using namespace std; const int L = 18; struct RMQ { vector<int> val; array<vector<int>, L> dp; int min(int i, int j) { return val[i] < val[j] ? i : j; } RMQ(vector<int> a) : val(a) { for (int i = 0; i < L; i++) { dp[i].resize(a.size()); } iota(dp[0].begin(), dp[0].end(), 0); for (int i = 0; i < L - 1; i++) { for (int j = 0; j + (2 << i) <= (int)a.size(); j++) { dp[i + 1][j] = min(dp[i][j], dp[i][j + (1 << i)]); } } } int query(int l, int r) { int t = __lg(r - l); return min(dp[t][l], dp[t][r - (1 << t)]); } }; struct RUPQ { int size; vector<int64_t> fenw; RUPQ(int n) : size(n), fenw(n + 1) {} void add(int l, int r, int v) { auto Add = [&](int i, int x) { for (i++; i <= size; i += i & -i) { fenw[i] += x; } }; Add(l, v); Add(r, -v); } int64_t get(int i) { int64_t ans = 0; for (i++; i > 0; i -= i & -i) { ans += fenw[i]; } return ans; } }; struct query { int i, S, T, X; long long Y; }; struct checkpoint { int P, C; bool operator<(const checkpoint& other) const { return C < other.C; } }; int main() { cin.tie(nullptr)->sync_with_stdio(false); int n, m, q; cin >> n >> m >> q; vector<vector<pair<int, int>>> g(n); for (int i = 0; i < n - 1; i++) { int x, y; cin >> x >> y; x--, y--; g[x].push_back({y, i}); g[y].push_back({x, i}); } vector<int> tin(n), tout(n), depth(n), edge(n - 1), val(2 * n), tour(2 * n), first(n); int timer = 0, pos = 0; auto DFS = [&](auto&& self, int u, int p) -> void { tin[u] = timer++; val[pos] = depth[u]; first[u] = pos; tour[pos++] = u; for (auto [v, i] : g[u]) { if (v != p) { edge[i] = v; depth[v] = depth[u] + 1; self(self, v, u); val[pos] = depth[u]; tour[pos++] = u; } } tout[u] = timer; }; DFS(DFS, 0, -1); RMQ rmq(val); auto LCA = [&](int u, int v) { if (first[u] > first[v]) { swap(u, v); } int p = rmq.query(first[u], first[v] + 1); return tour[p]; }; vector<checkpoint> points(m); for (auto &[P, C] : points) { cin >> P >> C; P--; P = edge[P]; } vector<query> Queries(q); vector<int> ans(q); for (auto &[i, S, T, X, Y] : Queries) { cin >> S >> T >> X >> Y; S--, T--; } for (int i = 0; i < q; i++) { Queries[i].i = i; } sort(points.begin(), points.end()); RUPQ in(n), out(n); for (auto [P, C] : points) { out.add(tin[P], tout[P], +1); } auto Solve = [&](auto&& self, int l, int r, vector<query>& queries) -> void { if (r - l == 1) { for (auto [i, S, T, X, Y] : queries) { ans[i] = X - (out.get(tin[S]) + out.get(tin[T]) - 2 * out.get(tin[LCA(S, T)])); } } else { int mid = (l + r) / 2; for (int i = l; i < mid; i++) { in.add(tin[points[i].P], tout[points[i].P], points[i].C); out.add(tin[points[i].P], tout[points[i].P], -1); } vector<query> lqueries, rqueries; for (auto [i, S, T, X, Y] : queries) { auto value = in.get(tin[S]) + in.get(tin[T]) - 2 * in.get(tin[LCA(S, T)]); if (value > Y) { lqueries.push_back({i, S, T, X, Y}); } else { rqueries.push_back({i, S, T, X, Y}); } } vector<query>().swap(queries); self(self, mid, r, rqueries); vector<query>().swap(rqueries); for (int i = l; i < mid; i++) { in.add(tin[points[i].P], tout[points[i].P], -points[i].C); out.add(tin[points[i].P], tout[points[i].P], +1); } self(self, l, mid, lqueries); vector<query>().swap(lqueries); } }; Solve(Solve, 0, m + 1, Queries); for (int i = 0; i < q; i++) { cout << max(-1, ans[i]) << "\n"; } }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...