Submission #1310141

#TimeUsernameProblemLanguageResultExecution timeMemory
1310141HostekTwo Currencies (JOI23_currencies)C++20
0 / 100
4 ms1340 KiB
// https://oj.uz/problem/view/JOI23_currencies #include <bits/stdc++.h> using namespace std; constexpr int sizik = 200005, L = 18; #define ar std::array #define vec std::vector typedef long long ll; vec<ar<int, 2>> kra[sizik]; ar<int, 2> kraw_[sizik]; ll ans[sizik]; int silver_cnt[sizik]; int depth[sizik], pre[sizik], post[sizik], timer = 0; ar<int, L + 1> up[sizik]; ar<int, L + 1> IleNaG[sizik]; int edge_to_node[sizik]; int Ile[sizik]; ll bit_cost[sizik]; int bit_cnt[sizik]; void bit_update(int idx, ll val_cost, int val_cnt) { for (; idx < sizik; idx += idx & -idx) { bit_cost[idx] += val_cost; bit_cnt[idx] += val_cnt; } } void range_update(int u, ll val_cost, int val_cnt) { bit_update(pre[u], val_cost, val_cnt); bit_update(post[u] + 1, -val_cost, -val_cnt); } ll query_cost(int idx) { ll sum = 0; for (; idx > 0; idx -= idx & -idx) sum += bit_cost[idx]; return sum; } int query_cnt(int idx) { int sum = 0; for (; idx > 0; idx -= idx & -idx) sum += bit_cnt[idx]; return sum; } void DFS(int v, int p, int czk, int edge_idx) { depth[v] = depth[p] + 1; pre[v] = ++timer; if (edge_idx != -1) edge_to_node[edge_idx] = v; up[v][0] = p; for (int i = 1; i <= L; ++i) up[v][i] = up[up[v][i - 1]][i - 1]; IleNaG[v][0] = czk; for (int i = 1; i <= L; ++i) { IleNaG[v][i] = IleNaG[v][i - 1] + IleNaG[up[v][i - 1]][i - 1]; } for (const auto& [u, i] : kra[v]) { if (u != p) { DFS(u, v, Ile[i], i); } } post[v] = timer; } bool is_ancestor(int u, int v) { return pre[u] <= pre[v] && post[u] >= post[v]; } int lca(int u, int v) { if (is_ancestor(u, v)) return u; if (is_ancestor(v, u)) return v; for (int i = L; i >= 0; --i) { if (!is_ancestor(up[u][i], v)) u = up[u][i]; } return up[u][0]; } int gn_helper(int v, int l) { int wyn = 0; for (int i = L; i >= 0; --i) { if (!is_ancestor(up[v][i], l)) { wyn += IleNaG[v][i]; v = up[v][i]; } } if (v != l) wyn += IleNaG[v][0]; return wyn; } int getNum(int v1, int v2) { int l = lca(v1, v2); return gn_helper(v1, l) + gn_helper(v2, l); } vec<int> mids[sizik]; ar<int, 2> pk[sizik]; int midFunc(int gp, int gk) { return (gp + gk) / 2; } void clear_bits() { for (int i = 0; i <= timer + 1; ++i) { bit_cost[i] = 0; bit_cnt[i] = 0; } } void solve() { int n, m, q; std::cin >> n >> m >> q; for (int i = 1; i <= n - 1; i++) { auto& [a, b] = kraw_[i]; std::cin >> a >> b; kra[a].push_back({b, i}); kra[b].push_back({a, i}); } std::vector<ar<int, 2>> CP(m); for (auto& [edge_idx, cost] : CP) { std::cin >> edge_idx >> cost; Ile[edge_idx]++; } std::sort(CP.begin(), CP.end(), [](const ar<int, 2>& a, const ar<int, 2>& b) { return a[1] < b[1]; }); DFS(1, 1, 0, -1); std::vector<ar<int, 4>> mieszkancy(q + 1); for (int i = 1; i <= q; ++i) { auto& [s, t, x, y] = mieszkancy[i]; std::cin >> s >> t >> x >> y; int total_checkpoints = getNum(s, t); ans[i] = (ll)x - total_checkpoints; pk[i] = {0, m}; mids[(0 + m) / 2].push_back(i); } int zostalo = q; while (zostalo) { clear_bits(); for (int i = 0; i <= m; i++) { if (i > 0) { int edge = CP[i - 1][0]; int cost = CP[i - 1][1]; int u = edge_to_node[edge]; range_update(u, cost, 1); } if (mids[i].empty()) continue; for (const auto u : mids[i]) { auto& [p, k] = pk[u]; int s = mieszkancy[u][0]; int t = mieszkancy[u][1]; int l = lca(s, t); ll y_lim = mieszkancy[u][3]; ll current_cost = query_cost(pre[s]) + query_cost(pre[t]) - 2 * query_cost(pre[l]); int current_cnt = query_cnt(pre[s]) + query_cnt(pre[t]) - 2 * query_cnt(pre[l]); if (current_cost <= y_lim) { silver_cnt[u] = current_cnt; p = i + 1; } else { k = i - 1; } if (p <= k) { mids[midFunc(p, k)].push_back(u); } else { zostalo--; } } mids[i].clear(); } } for (int i = 1; i <= q; i++) { ll res = ans[i] + silver_cnt[i]; std::cout << std::max(-1LL, res) << '\n'; } } int32_t main() { std::ios_base::sync_with_stdio(0); std::cin.tie(0); std::cout.tie(0); solve(); 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...