제출 #790320

#제출 시각아이디문제언어결과실행 시간메모리
790320JohannTwo Currencies (JOI23_currencies)C++14
100 / 100
2770 ms229504 KiB
#include "bits/stdc++.h" using namespace std; typedef long long ll; typedef vector<int> vi; typedef vector<vi> vvi; typedef pair<ll, ll> pii; pii operator+(const pii &a, const pii &b) { return {a.first + b.first, a.second + b.second}; } typedef vector<pii> vpii; typedef vector<vpii> vvpii; #define all(x) (x).begin(), (x).end() #define sz(x) (int)(x).size() int N, M, Q; vi A, B; vector<vector<ll>> C; vpii D; // what to delete vvpii adj; vi in, out; vvi vorg; vi ein, eout; // edges to corresponding in and outs vi R; // binary search those roots struct segtree { int size; vpii arr; vi L, R; vi roots; int newNode() { arr.push_back({0, 0}), L.push_back(-1), R.push_back(-1); return sz(arr) - 1; } void init(int _size) { size = 1; while (size < _size) size *= 2; arr.assign(2 * size, {0, 0}); L.assign(2 * size, -1), R.assign(2 * size, -1); roots.push_back(1); for (int i = 1; i < size; ++i) L[i] = 2 * i, R[i] = 2 * i + 1; } int add(int i, pii v) { int idx = newNode(); add(i, v, idx, roots.back(), 0, size); roots.push_back(idx); return idx; } void add(int i, pii v, int newX, int oldX, int lx, int rx) { L[newX] = L[oldX], R[newX] = R[oldX], arr[newX] = arr[oldX]; if (rx - lx == 1) { arr[newX] = arr[oldX] + v; return; } int m = (lx + rx) / 2; int idx = newNode(); if (i < m) { L[newX] = idx; add(i, v, L[newX], L[oldX], lx, m); } else { R[newX] = idx; add(i, v, R[newX], R[oldX], m, rx); } arr[newX] = arr[L[newX]] + arr[R[newX]]; } pii summe(int l, int r, int x) { return summe(l, r, x, 0, size); } pii summe(int l, int r, int x, int lx, int rx) { if (l <= lx && rx <= r) return arr[x]; if (r <= lx || rx <= l) return {0, 0}; int m = (lx + rx) / 2; pii a = summe(l, r, L[x], lx, m); pii b = summe(l, r, R[x], m, rx); return a + b; // return {a.first + b.first, a.second + b.second}; } }; segtree seg; void dfs(int v, int p, int e, int &idx) { vorg[v][0] = p; for (int i = 1; i < sz(vorg[v]); ++i) vorg[v][i] = vorg[vorg[v][i - 1]][i - 1]; in[v] = idx; if (e != -1) ein[e] = idx; ++idx; for (pii ed : adj[v]) { if (ed.first == p) continue; dfs(ed.first, v, ed.second, idx); } out[v] = idx; if (e != -1) eout[e] = idx; ++idx; } bool isVorg(int a, int b) { return in[a] <= in[b] && out[b] <= out[a]; } int lca(int a, int b) { if (isVorg(a, b)) return a; if (isVorg(b, a)) return b; int tmp; for (int i = sz(vorg[0]) - 1; i >= 0; --i) { tmp = vorg[a][i]; if (!isVorg(tmp, b)) a = tmp; } return vorg[a][0]; } int main() { ios::sync_with_stdio(false); cin.tie(0); cin >> N >> M >> Q; adj.resize(N); A.resize(N - 1), B.resize(N - 1); for (int i = 0; i < N - 1; ++i) { cin >> A[i] >> B[i]; --A[i], --B[i]; adj[A[i]].push_back({B[i], i}); adj[B[i]].push_back({A[i], i}); } in.resize(N), out.resize(N); ein.resize(N - 1), eout.resize(N - 1); vorg.assign(N, vi(ceil(log2(N)) + 1)); int idx = 0; dfs(0, 0, -1, idx); C.resize(N - 1); for (int i = 0, p, c; i < M; ++i) { cin >> p >> c; --p; C[p].push_back(c); D.push_back({c, p}); } seg.init(2 * N); for (int i = 0; i < N - 1; ++i) { if (!C[i].empty()) { seg.add(ein[i], {0, accumulate(all(C[i]), 0LL)}); seg.add(eout[i], {0, -accumulate(all(C[i]), 0LL)}); } } sort(all(D)); reverse(all(D)); R.push_back(seg.roots.back()); for (pii d : D) { seg.add(ein[d.second], {1, -d.first}); R.push_back(seg.add(eout[d.second], {-1, d.first})); } while (Q--) { int s, t; ll x, y; cin >> s >> t >> x >> y; --s, --t; int lc = lca(s, t); int l = 0, r = sz(R), m; while (l < r) { m = (l + r) / 2; pii ans = seg.summe(in[lc] + 1, in[s] + 1, R[m]) + seg.summe(in[lc] + 1, in[t] + 1, R[m]); if (ans.second > y) l = m + 1; else r = m; } if (l == sz(R)) cout << "-1\n"; else { pii ans = seg.summe(in[lc] + 1, in[s] + 1, R[l]) + seg.summe(in[lc] + 1, in[t] + 1, R[l]); if (ans.second <= y && ans.first <= x) cout << x - ans.first << "\n"; else cout << "-1\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...