Submission #1262069

#TimeUsernameProblemLanguageResultExecution timeMemory
1262069niepamietamhaslaTwo Currencies (JOI23_currencies)C++20
100 / 100
942 ms171076 KiB
#include <bits/stdc++.h> using namespace std; typedef long long ll; #define pii pair<ll,ll> const ll MAXN = 1e5 + 5; const ll INF = 2e12; map<ll,ll> scal; map<ll,ll> wtyl; ll cnt = 1; struct Node{ ll suma; ll ilosc; Node *l, *r; Node(ll x, ll y) : suma(x), ilosc(y) {}; Node(Node *ll, Node *rr) : suma(ll->suma + rr->suma), ilosc(ll->ilosc + rr->ilosc), l(ll), r(rr) {}; }; vector<pair<ll, vector<ll>>> graf[MAXN]; ll gl[MAXN]; ll ile[MAXN]; ll przodek[MAXN][17]; Node *roots[MAXN]; struct d{ ll a; ll b; vector<ll> koszty; }; vector<d> kraw; const ll base = 1 << 17; Node *build(ll akt_a = 1, ll akt_b = base){ if(akt_a == akt_b) return new Node(0ll, 0ll); ll mid = (akt_a + akt_b) / 2; return new Node(build(akt_a, mid), build(mid + 1, akt_b)); } Node *dodaj(Node *w, ll ind, ll akt_a = 1, ll akt_b = base){ if(akt_a == akt_b){ return new Node(w->suma + wtyl[ind], w->ilosc + 1); } ll mid = (akt_a + akt_b) / 2; if(ind <= mid){ return new Node(dodaj(w->l, ind, akt_a, mid), w->r); } else{ return new Node(w->l, dodaj(w->r, ind, mid + 1, akt_b)); } } set<ll> koszty; ll ktory[MAXN]; ll it = 2; void dfs(ll v, ll p){ for(auto u : graf[v]){ if(u.first == p) continue; gl[u.first] = gl[v] + 1; przodek[u.first][0] = v; ile[u.first] = ile[v] + u.second.size(); for(ll j = 1; j < 17; ++j){ przodek[u.first][j] = przodek[przodek[u.first][j-1]][j-1]; } if(u.second.size() == 0) ktory[u.first] = ktory[v]; for(ll j = 0; j < u.second.size(); ++j){ if(j == 0){ roots[it] = dodaj(roots[ktory[v]], u.second[j], 1, base); ktory[u.first] = it; ++it; } else{ roots[it] = dodaj(roots[ktory[u.first]], u.second[j], 1, base); ktory[u.first] = it; ++it; } } dfs(u.first, v); } } ll LCA(ll x, ll y){ if(x == y) return x; if(gl[x] < gl[y]) swap(x, y); for(ll j = 16; j >= 0; --j){ if(gl[x] - (1 << j) >= gl[y]){ x = przodek[x][j]; } } if(x == y) return x; for(ll j = 16; j >= 0; --j){ if(gl[x] >= (1 << j) and przodek[x][j] != przodek[y][j]){ x = przodek[x][j]; y = przodek[y][j]; } } return przodek[x][0]; } ll obl(Node *a, Node *b, Node *x, ll suma, ll akt_a, ll akt_b, ll currsuma){ if(akt_a == akt_b){ ll S = a->suma + b->suma - 2 * x->suma; ll L = a->ilosc + b->ilosc - 2 * x->ilosc; if(S == 0 or L == 0) return 0; else return min(L, (suma - currsuma) / (S / L)); } ll mid = (akt_a + akt_b) / 2; ll lewasuma = a->l->suma + b->l->suma - 2 * x->l->suma; ll lewailosc = a->l->ilosc + b->l->ilosc - 2 * x->l->ilosc; if(currsuma + lewasuma < suma){ return obl(a->r, b->r, x->r, suma, mid + 1, akt_b, currsuma + lewasuma) + lewailosc; } else{ return obl(a->l, b->l, x->l, suma, akt_a, mid, currsuma); } } int main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); ll n, m, q; cin >> n >> m >> q; ll a, b; for(ll i = 0; i < n-1; ++i){ cin >> a >> b; kraw.push_back({a, b}); } for(ll i = 0; i < m; ++i){ cin >> a >> b; kraw[a-1].koszty.push_back(b); koszty.insert(b); } for(auto u : koszty){ scal[u] = cnt; wtyl[cnt] = u; ++cnt; } for(auto &u : kraw){ graf[u.a].push_back({u.b, {}}); graf[u.b].push_back({u.a, {}}); for(auto &t : u.koszty){ t = scal[t]; graf[u.a].back().second.push_back(t); graf[u.b].back().second.push_back(t); } } roots[1] = build(); ktory[1] = 1; dfs(1, 0); ll c, d; for(ll i = 0; i < q; ++i){ cin >> a >> b >> c >> d; ll x = LCA(a, b); ll ans = c - (ile[a] + ile[b] - 2 * ile[x] - obl(roots[ktory[a]], roots[ktory[b]], roots[ktory[x]], d, 1, base, 0)); if(ans < 0) cout << -1 << "\n"; else cout << ans << "\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...