제출 #1029524

#제출 시각아이디문제언어결과실행 시간메모리
1029524adaawfTwo Currencies (JOI23_currencies)C++17
100 / 100
1494 ms71676 KiB
#include <iostream> #include <vector> #include <algorithm> using namespace std; #define int long long vector<int> g[100005], gg[100005]; int d[100005], ll[100005][19], u[100005], v[100005], f[100005], res[100005]; int l[100005], r[100005], dd[100005], da[100005], z = 0; void dfs(int x, int p) { dd[x] = ++z; ll[x][0] = p; for (int w : g[x]) { if (w == p) continue; d[w] = d[x] + 1; dfs(w, x); } da[x] = z; } void dfs2(int x, int p) { for (int w : g[x]) { if (w == p) continue; f[w] += f[x]; dfs2(w, x); } } int lca(int x, int y) { if (d[x] < d[y]) swap(x, y); int k = d[x] - d[y]; for (int i = 18; i >= 0; i--) { if (k & (1 << i)) { x = ll[x][i]; } } if (x == y) return x; for (int i = 18; i >= 0; i--) { if (ll[x][i] != ll[y][i]) { x = ll[x][i]; y = ll[y][i]; } } return ll[x][0]; } struct QUERY { int u, v, x, y, h, z; } b[100005]; pair<int, int> t[400005]; void update(int v, int tl, int tr, int x, int y, int z) { if (tl == tr) { t[v].first += y; t[v].second += z; return; } int mid = (tl + tr) / 2; if (mid >= x) update(v * 2, tl, mid, x, y, z); else update(v * 2 + 1, mid + 1, tr, x, y, z); t[v].first = t[v * 2].first + t[v * 2 + 1].first; t[v].second = t[v * 2].second + t[v * 2 + 1].second; } pair<int, int> sum(int v, int tl, int tr, int l, int r) { if (l > r) return {0, 0}; if (tl == l && tr == r) { return t[v]; } int mid = (tl + tr) / 2; pair<int, int> h = sum(v * 2, tl, mid, l, min(r, mid)), k = sum(v * 2 + 1, mid + 1, tr, max(l, mid + 1), r); return {h.first + k.first, h.second + k.second}; } signed main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); int n, m, q; cin >> n >> m >> q; for (int i = 1; i < n; i++) { cin >> u[i] >> v[i]; g[u[i]].push_back(v[i]); g[v[i]].push_back(u[i]); } dfs(1, 0); for (int i = 1; i <= 18; i++) { for (int j = 1; j <= n; j++) { ll[j][i] = ll[ll[j][i - 1]][i - 1]; } } vector<pair<int, int>> vv; for (int i = 1; i <= m; i++) { int x, c; cin >> x >> c; if (d[u[x]] < d[v[x]]) swap(u[x], v[x]); vv.push_back({c, u[x]}); f[u[x]]++; } dfs2(1, 0); sort(vv.begin(), vv.end()); for (int i = 1; i <= q; i++) { cin >> b[i].u >> b[i].v >> b[i].x >> b[i].y; int h = lca(b[i].u, b[i].v); res[i] = b[i].z = b[i].x - (f[b[i].u] + f[b[i].v] - f[h] * 2); l[i] = 0, r[i] = m - 1; b[i].h = h; } while (1) { for (int i = 0; i < m; i++) gg[i].clear(); for (int i = 1; i <= n * 4; i++) t[i] = {0, 0}; int flag = 0; for (int i = 1; i <= q; i++) { if (l[i] <= r[i]) { flag = 1; gg[(l[i] + r[i]) / 2].push_back(i); } } if (flag == 0) break; for (int i = 0; i < m; i++) { update(1, 1, n, dd[vv[i].second], vv[i].first, 1); if (da[vv[i].second] != n) update(1, 1, n, da[vv[i].second] + 1, -vv[i].first, -1); for (int w : gg[i]) { pair<int, int> p = sum(1, 1, n, 1, dd[b[w].u]), pa = sum(1, 1, n, 1, dd[b[w].v]), pb = sum(1, 1, n, 1, dd[b[w].h]), pp; pp = make_pair(p.first + pa.first - pb.first * 2, p.second + pa.second - pb.second * 2); if (pp.first <= b[w].y) { res[w] = max(res[w], b[w].z + pp.second); l[w] = i + 1; } else r[w] = i - 1; } } } for (int i = 1; i <= q; i++) cout << max(res[i], -1ll) << '\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...