제출 #945987

#제출 시각아이디문제언어결과실행 시간메모리
945987petezaTwo Currencies (JOI23_currencies)C++14
100 / 100
923 ms130296 KiB
#include <bits/stdc++.h> using namespace std; using ll = long long; struct node { node *l = NULL, *r = NULL; int sz = 0; ll sum = 0; } *root[100005]; int n, m, q; ll a, b, c, d; pair<int, int> edges[100005]; vector<int> prices[100005]; vector<int> adj[100005]; int par[100005][22], dep[100005]; node* build(int l, int r) { auto it = new node(); if(l == r) return it; int mid = (l+r) >> 1; it->l = build(l, mid); it->r = build(mid+1, r); return it; } node *upd(node*&old, int l, int r, int tgt, int val) { auto it = new node(); if(l == r) {it->sz=1; it->sum = val; return it;} int mid = (l+r) >> 1; if(tgt <= mid) it->l = upd(old->l, l, mid, tgt, val), it->r = old->r; else it->r = upd(old->r, mid+1, r, tgt,val), it->l = old->l; it->sz = it->l->sz + it->r->sz ; it->sum = it->l->sum + it->r->sum; return it; } void dfsdep(int x, int p = 0) { dep[x] = dep[p] + 1; par[x][0] = p; for(int i=1;i<20;i++) par[x][i] = par[par[x][i-1]][i-1]; for(int e:adj[x]) { if(e != p) dfsdep(e, x); } } int lca(int a, int b) { if(dep[a] > dep[b]) swap(a, b); for(int i=19;i>=0;i--) if(dep[a] <= dep[par[b][i]]) b = par[b][i]; if(a == b) return a; for(int i=19;i>=0;i--) if(par[a][i] != par[b][i]) a = par[a][i], b = par[b][i]; return par[a][0]; } int pos[100005]; vector<pair<int, int>> edgesprices; void dfspart2(int x, int p = 0) { root[x] = root[p]; for(auto e:prices[x]) { root[x] = upd(root[x], 1, m, pos[e], edgesprices[pos[e]-1].first); } //cout << x << ": " << root[x]->sz << "-> " << root[x]->sum << '\n'; for(int e:adj[x]) { if(e != p) dfspart2(e, x); } } int qr(node *& ra, node*& rb, node*& lca, int l, int r, ll tgt) { //cout << l << ", " << r << '\n'; if(l == r) return ((ra->sz + rb->sz - lca->sz*2) && (tgt >= ra->sum + rb->sum - lca->sum*2)); if(!ra) return 0; int mid = (l+r) >> 1; ll silleft = ra->l->sum + rb->l->sum - lca->l->sum*2; if(silleft <= tgt) return ra->l->sz + rb->l->sz - lca->l->sz*2 + qr(ra->r, rb->r, lca->r, mid+1, r, tgt-silleft); else return qr(ra->l, rb->l, lca->l, l, mid, tgt); } int main() { //cin.tie(0) -> sync_with_stdio(0); cin >> n >> m >> q; for(int i=1;i<n;i++) { cin >> a >> b; adj[a].push_back(b); adj[b].push_back(a); edges[i] = {a, b}; } root[0] = build(1, m); dfsdep(1); for(int i=1;i<=m;i++) { cin >> a >> b; if(dep[edges[a].first] > dep[edges[a].second]) swap(edges[a].first, edges[a].second); prices[edges[a].second].emplace_back(i); edgesprices.emplace_back(b, i); } sort(edgesprices.begin(), edgesprices.end()); for(int i=0;i<m;i++) pos[edgesprices[i].second] = i+1; dfspart2(1); while(q--) { cin >> a >> b >> c >> d; int lcab = lca(a, b); ll silvercnt = root[a]->sz + root[b]->sz - 2*root[lcab]->sz; cout << max(-1ll, c-(silvercnt-qr(root[a], root[b], root[lcab], 1, m, d))) << '\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...