제출 #1252482

#제출 시각아이디문제언어결과실행 시간메모리
1252482giaminhhaTwo Currencies (JOI23_currencies)C++20
100 / 100
1070 ms40996 KiB
#include <bits/stdc++.h> #define ll long long #define pb push_back #define eb emplace_back #define pu push #define ins insert #define fi first #define se second #define all(a) a.begin(),a.end() #define fastio ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0); using namespace std; //mt19937 mt(chrono::steady_clock::now().time_since_epoch().count()); typedef pair<int, int> pii; const int mod = 2147483647; const int inf = 1e9 + 7; const int N = 1e5 + 5; int h[N], tin[N], tout[N], t = 0; int up[N][20]; vector<int> adj[N]; void dfs(int u, int par){ tin[u] = ++t; for(int v : adj[u]){ if(v == par) continue; h[v] = h[u] + 1; up[v][0] = u; dfs(v, u); } tout[u] = t; } int lca(int u, int v){ if(h[u] < h[v]) swap(u, v); int diff = h[u] - h[v]; for(int i = 18; i >= 0; i--){ if(diff >= (1 << i)){ diff -= (1 << i); u = up[u][i]; } } if(u == v) return u; for(int i = 18; i >= 0; i--){ if(up[u][i] != up[v][i]){ u = up[u][i]; v = up[v][i]; } } return up[u][0]; } struct Fenwick{ vector<ll> f; int n; Fenwick(int _n){ n = _n; f.resize(n + 5, 0); } void update_point(int u, int val){ for(; u < N; u += u&(-u)){ f[u] += val; } } void update_range(int u, int v, ll val){ update_point(u, val); update_point(v + 1, -val); } ll get(int u){ ll ans = 0; for(; u > 0; u -= u&(-u)){ ans += f[u]; } return ans; } }; bool is_ances(int u, int v){ return tin[u] <= tin[v] && tout[v] <= tout[u]; } vector<int> bucket[N]; int leftb[N], rightb[N], ans[N]; pair<ll, int> p[N]; int S[N], T[N]; ll X[N], Y[N]; signed main(){ fastio int n, m, q; cin >> n >> m >> q; vector<pii> edges; for(int i = 1; i < n; i++){ int u, v; cin >> u >> v; adj[u].pb(v); adj[v].pb(u); edges.pb({u, v}); } for(int i = 1; i <= m; i++){ int x; ll y; cin >> x >> y; p[i] = {y, x}; } h[1] = 0; dfs(1, 1); for(int i = 0; i < edges.size(); i++){ if(is_ances(edges[i].se, edges[i].fi)) swap(edges[i].fi, edges[i].se); } up[1][0] = 1; for(int i = 1; i <= 18; i++){ for(int j = 1; j <= n; j++) up[j][i] = up[up[j][i - 1]][i - 1]; } for(int i = 1; i <= q; i++){ cin >> S[i] >> T[i] >> X[i] >> Y[i]; leftb[i] = 0; rightb[i] = m; ans[i] = inf; } sort(p + 1, p + m + 1); while(true){ bool ck = false; for(int i = 1; i <= q; i++){ if(leftb[i] < rightb[i]){ int mid = (leftb[i] + rightb[i] + 1) >> 1; bucket[mid].pb(i); ck = true; } } if(!ck) break; Fenwick cost_tree(N), count_tree(N); for(int i = 0; i <= m; i++){ if(i > 0){ int u = edges[p[i].se - 1].se; cost_tree.update_range(tin[u], tout[u], p[i].fi); count_tree.update_range(tin[u], tout[u], 1); } for(int idx : bucket[i]){ ll gold_needed = count_tree.get(tin[S[idx]]) + count_tree.get(tin[T[idx]]) - 2 * count_tree.get(tin[lca(S[idx], T[idx])]); ll silver_needed = cost_tree.get(tin[S[idx]]) + cost_tree.get(tin[T[idx]]) - 2 * cost_tree.get(tin[lca(S[idx], T[idx])]); if(silver_needed <= Y[idx]){ ans[idx] = gold_needed; leftb[idx] = i; } else rightb[idx] = i - 1; } bucket[i].clear(); } } Fenwick bit(N); for(int i = 1; i <= m; i++){ int v = edges[p[i].se - 1].se; bit.update_range(tin[v], tout[v], 1); } for(int i = 1; i <= q; i++){ if(ans[i] >= inf) ans[i] = 0; cout << max((ll)-1, X[i] - (bit.get(tin[S[i]]) + bit.get(tin[T[i]]) - 2 * bit.get(tin[lca(S[i], T[i])]) - ans[i])) << '\n'; } 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...