제출 #1247670

#제출 시각아이디문제언어결과실행 시간메모리
1247670raphaeltfaTwo Currencies (JOI23_currencies)C++20
100 / 100
622 ms45772 KiB
#include <bits/stdc++.h> using namespace std; #define int long long using namespace std; const int LOG = 19, inf = 1e18; vector<vector<int>> adj, up; vector<pair<int, int>> edges, queries, check, coin; vector<int> in_time, out_time; int timer = 0; struct Fenwick{ int n; vector<int> tree; Fenwick(int _n) : n(_n + 5), tree(_n + 5, 0) {} void _update(int pos, int val){ for(pos++; pos < n; pos += pos & (-pos)) tree[pos] += val; } int query(int pos){ int res = 0; for(pos++; pos > 0; pos -= pos & (-pos)) res += tree[pos]; return res; } void update(int in, int out, int val){ _update(in, val), _update(out + 1, -val); } }; void dfs(int u, int par){ in_time[u] = ++timer; up[u][0] = par; for(int i = 1; i < LOG; i++) if(up[u][i - 1] != -1) up[u][i] = up[up[u][i - 1]][i - 1]; for(const int &v : adj[u]) if(v != par) dfs(v, u); out_time[u] = timer; } bool is_ances(int u, int v){ return in_time[u] <= in_time[v] && out_time[v] <= out_time[u]; } int _lca(int u, int v){ if(is_ances(u, v)) return u; if(is_ances(v, u)) return v; for(int i = LOG - 1; i >= 0; i--) if(up[u][i] != -1 &&!is_ances(up[u][i], v)) u = up[u][i]; return up[u][0]; } void solve(){ int n, m, q; cin >> n >> m >> q; adj.resize(n + 1), up.resize(n + 1, vector<int> (LOG, -1)); in_time.resize(n + 1), out_time.resize(n + 1); for(int i = 1; i < n; i++) { int u, v; cin >> u >> v; edges.push_back({u, v}); adj[u].push_back(v), adj[v].push_back(u); } for(int i = 0; i < m; i++){ int p, c; cin >> p >> c; check.push_back({p, c}); } sort(check.begin(), check.end(), [&](pair<int, int> a, pair<int, int> b){ if(a.second == b.second) return a.first < b.first; return a.second < b.second; }); dfs(1, -1); for(int i = 1; i < n; i++){ if(is_ances(edges[i - 1].second, edges[i - 1].first)) swap(edges[i - 1].first, edges[i - 1].second); } vector<pair<int, int>> queries(q); vector<int> lca(q); for(int i = 0; i < q; i++){ int g, s; cin >> queries[i].first >> queries[i].second >> g >> s; coin.push_back({g, s}); lca[i] = _lca(queries[i].first, queries[i].second); } vector<int> le(q, 0), ri(q, m), res(q, inf); bool cont = true; int turn = 0; while(cont){ turn++; cont = false; vector<vector<int>> bucket(m + 1); for(int i = 0; i < q; i++){ if(le[i] != ri[i]){ cont = true; int mid = (le[i] + ri[i] + 1) / 2; bucket[mid].push_back(i); } } Fenwick bit_sil(timer), bit_gol(timer); for(int i = 0; i <= m; i++){ if(i != 0){ const auto &[p, c] = check[i - 1]; bit_sil.update(in_time[edges[p - 1].second], out_time[edges[p - 1].second], c); bit_gol.update(in_time[edges[p - 1].second], out_time[edges[p - 1].second], 1); } for(const int &q : bucket[i]){ const auto &[u, v] = queries[q]; int l = lca[q]; int sil = bit_sil.query(in_time[u]) + bit_sil.query(in_time[v]) - 2 * bit_sil.query(in_time[l]); int gol = bit_gol.query(in_time[u]) + bit_gol.query(in_time[v]) - 2 * bit_gol.query(in_time[l]); if(sil <= coin[q].second) le[q] = i, res[q] = gol; else ri[q] = i - 1; } } } Fenwick bit(timer); for(int i = 0; i < m; i++){ const auto &[p, c] = check[i]; int idx = edges[p - 1].second; bit.update(in_time[idx], out_time[idx], 1); } for(int i = 0; i < q; i++){ const auto &[u, v] = queries[i]; if(res[i] == inf) res[i] = 0; cout << max((long long)-1, coin[i].first - (bit.query(in_time[u]) + bit.query(in_time[v]) - 2 * bit.query(in_time[lca[i]]) - res[i])) << "\n"; } } signed main(){ ios_base::sync_with_stdio(false); cin.tie(nullptr); int test; test = 1; //cin >> test; while(test--) solve(); }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...