제출 #1304252

#제출 시각아이디문제언어결과실행 시간메모리
1304252KietJTwo Currencies (JOI23_currencies)C++17
100 / 100
2104 ms30180 KiB
#include <bits/stdc++.h> using namespace std; #define ll long long #define f first #define s second #define sz(a) (int)((a).size()) #define all(a) (a).begin(), (a).end() #define uni(a) sort(all(a)), (a).resize(unique(all(a)) - (a).begin()) typedef pair <int, int> ii; const int N = 1e5 + 20; int n, m, q, timer; int in[N], ou[N], node[N], depth[N], up[N][20], ans[N], l[N], r[N]; vector <int> graph[N]; vector <ii> arr, ask; ii edge[N]; ll f[N], sum[N]; void dfs(int u = 1, int p = -1) { in[u] = ++timer; node[timer] = u; for (int i = 1; i <= 17; i++) up[u][i] = up[up[u][i - 1]][i - 1]; for (int i = 0; i < sz(graph[u]); i++) if (graph[u][i] != p) { int v = graph[u][i]; depth[v] = depth[u] + 1; up[v][0] = u; dfs(v, u); } ou[u] = timer; } int lca(int u, int v) { if (depth[u] < depth[v]) swap(u, v); int k = depth[u] - depth[v]; for (int i = 0; i <= 17; i++) if (k & (1 << i)) { u = up[u][i]; } if (u == v) return u; for (int i = 17; i >= 0; i--) if (up[u][i] != up[v][i]) { u = up[u][i]; v = up[v][i]; } return up[u][0]; } void upd(int x, ll y) { for (int i = x; i <= n + 10; i += i & (-i)) f[i] += y; } ll get(int x) { ll s = 0; for (int i = x; i >= 1; i -= i & (-i)) s += f[i]; return s; } struct qry { ll x, y, s, t; } qr[N]; void solve() { cin >> n >> m >> q; for (int i = 1; i < n; i++) { int u, v; cin >> u >> v; graph[u].push_back(v); graph[v].push_back(u); edge[i] = {u, v}; } for (int i = 1; i <= m; i++) { int x, y; cin >> x >> y; arr.push_back({y, x}); } dfs(); for (int i = 1; i < n; i++) { if (depth[edge[i].s] < depth[edge[i].f]) swap(edge[i].f, edge[i].s); } for (int i = 0; i < sz(arr); i++) { arr[i].s = edge[arr[i].s].s; } sort(all(arr)); for (int i = 1; i <= q; i++) { cin >> qr[i].s >> qr[i].t >> qr[i].x >> qr[i].y; l[i] = 0, r[i] = m; ans[i] = -1; } while (1) { ask.clear(); for (int i = 1; i <= q; i++) { if (l[i] <= r[i]) { ask.push_back({(l[i] + r[i]) / 2, i}); } } sort(all(ask)); if (sz(ask) == 0) break; for (int i = 1; i <= n + 10; i++) { f[i] = 0; } for (int i = 0, j = 0; i < sz(ask); i++) { while (j < sz(arr) && j <= ask[i].f) { upd(in[arr[j].s], arr[j].f); upd(ou[arr[j].s] + 1, -arr[j].f); j++; } int u = qr[ask[i].s].s, v = qr[ask[i].s].t; int p = lca(u, v); ll su = get(in[u]); ll sv = get(in[v]); ll sp = get(in[p]); sum[ask[i].s] = su + sv - 2 * sp; } for (int i = 1; i <= q; i++) { if (sum[i] <= qr[i].y) { ans[i] = (l[i] + r[i]) / 2; l[i] = (l[i] + r[i]) / 2 + 1; } else { r[i] = (l[i] + r[i]) / 2 - 1; } } } for (int i = 1; i <= n + 10; i++) { f[i] = 0; } ask.clear(); for (int i = 1; i <= q; i++) { ask.push_back({ans[i], i}); } sort(all(ask)); for (int i = sz(ask) - 1, j = sz(arr) - 1; i >= 0; i--) { while (j >= 0 && j > ask[i].f) { upd(in[arr[j].s], 1); upd(ou[arr[j].s] + 1, -1); j--; } int u = qr[ask[i].s].s, v = qr[ask[i].s].t; int p = lca(u, v); ll su = get(in[u]); ll sv = get(in[v]); ll sp = get(in[p]); ans[ask[i].s] = su + sv - 2 * sp; } for (int i = 1; i <= q; i++) { if (ans[i] <= qr[i].x) { cout << qr[i].x - ans[i] << '\n'; } else { cout << -1 << '\n'; } } } int main() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); // freopen("a.inp", "r", stdin); // freopen("a.out", "w", stdout); int t = 1; // cin >> t; while (t--) { solve(); } 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...