제출 #955628

#제출 시각아이디문제언어결과실행 시간메모리
955628vjudge1Two Currencies (JOI23_currencies)C++17
100 / 100
2013 ms129108 KiB
#pragma GCC optimize("O3,unroll-loops") #pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt") // ^ desperate #include<bits/stdc++.h> using namespace std; #define ll long long int const N = 1e5+10; int const M = 1e7; struct S{ int l, r; ll v; int c; } seg[M]; int rt[N]; int segcnt = 0; int nodeseg1(ll v, int c){ seg[segcnt].v = v; seg[segcnt].c = c; return segcnt++; }; int nodeseg2(int l, int r){ seg[segcnt].l = l; seg[segcnt].r = r; seg[segcnt].v = seg[l].v + seg[r].v; seg[segcnt].c = seg[l].c + seg[r].c; return segcnt++; } int buildseg(int l, int r){ if (l==r) return nodeseg1(0,0); int m = (l+r)/2; return nodeseg2(buildseg(l,m),buildseg(m+1,r)); } int updseg(int u, int pos, ll v, int l, int r){ if (l>pos||r<pos) return u; if (l==r) return nodeseg1(seg[u].v + v, seg[u].c+(v>0?1:-1)); int m = (l+r)/2; int _l = updseg(seg[u].l, pos, v, l, m), _r = updseg(seg[u].r, pos, v, m+1, r); return nodeseg2(_l, _r); } pair<ll,ll> query(int u, int i, int j, int l, int r){ if (i>j) return make_pair(0LL,0LL); if (i <= l && r <= j) return make_pair(seg[u].v, seg[u].c); int m = (l+r)/2; pair<ll,ll> ql = query(seg[u].l, i, min(m,j), l, m), qr = query(seg[u].r, max(m+1,i), j, m+1, r); return make_pair(ql.first+qr.first, ql.second+qr.second); } struct Edge{ int u, v; Edge() {} Edge(int u, int v) : u(u), v(v) {} int get(int x) { return u^v^x; } }; vector<Edge> E; vector<int> G[N]; int tin[N], tout[N], B[N], tt, dd; int ent[N], tt2; pair<int,int> lcas[6*N]; void dfs(int u){ ent[u] = ++tt2; lcas[tt2] = make_pair(dd, u); for (int i: G[u]){ int v = E[i].get(u); if (ent[v]) continue; B[v] = i; tin[i] = ++tt; ++dd; dfs(v); --dd; tout[i] = ++tt; lcas[++tt2] = make_pair(dd, u); } } void build(){ for (int i = 0; i <= tt2; ++i) lcas[i+tt2+1] = lcas[i]; for (int i=tt2; i; --i) lcas[i] = min(lcas[i<<1], lcas[i<<1|1]); } int lca(int u, int v){ pair<int,int> pp = make_pair(1e8, 0); int aa = ent[u], bb = ent[v]; if (aa > bb) swap(aa, bb); for (aa += tt2+1, bb += tt2+2; aa < bb; aa >>= 1, bb >>= 1){ if (aa&1) pp = min(pp, lcas[aa++]); if (bb&1) pp = min(pp, lcas[--bb]); } return pp.second; } int main(){ ios::sync_with_stdio(false); cin.tie(nullptr); int n, m, q; cin >> n >> m >> q; E.emplace_back(0, 1); for (int i = 1; i < n; ++i){ int u, v; cin >> u >> v; E.emplace_back(u, v); } vector<pair<ll,int>> upd; for (int i = 1; i <= m; ++i){ int p; ll c; cin >> p >> c; upd.emplace_back(c,p); } sort(upd.begin(), upd.end()); for (int i = 0; i < (int)E.size(); ++i){ G[E[i].u].push_back(i); G[E[i].v].push_back(i); } dfs(0); build(); int root = buildseg(1, tt); for (int i = 0; i < (int)upd.size(); ++i){ auto x = upd[i]; int idx; ll w; tie(w, idx) = x; root = rt[i] = updseg(root, tin[idx], w, 1, tt); root = rt[i] = updseg(root, tout[idx], -w, 1, tt); } for (int i = 0; i < q; ++i){ int u, v; ll x, y; cin >> u >> v >> x >> y; int p = lca(u,v); int lvert = 0, rvert = upd.size()-1; ll xx=0, yy=0; while (lvert <= rvert){ int mvert = (lvert+rvert+1)/2; pair<ll,ll> uq = query(rt[mvert], tin[B[1]], tin[B[u]], 1, tt); pair<ll,ll> vq = query(rt[mvert], tin[B[1]], tin[B[v]], 1, tt); pair<ll,ll> pq = query(rt[mvert], tin[B[1]], tin[B[p]], 1, tt); yy = uq.first+vq.first-pq.first*2; ll x2 = uq.second+vq.second-pq.second*2; if (yy <= y) xx = x2, lvert=mvert+1; else rvert=mvert-1; } pair<ll,ll> uq = query(root, tin[B[1]], tin[B[u]], 1, tt); pair<ll,ll> vq = query(root, tin[B[1]], tin[B[v]], 1, tt); pair<ll,ll> pq = query(root, tin[B[1]], tin[B[p]], 1, tt); ll xz = uq.second+vq.second-pq.second*2; if (x < xz-xx) { cout << -1 << '\n'; } else { cout << (x-xz+xx) << '\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...