제출 #1126300

#제출 시각아이디문제언어결과실행 시간메모리
1126300PekibanTwo Currencies (JOI23_currencies)C++20
0 / 100
12 ms13384 KiB
#include <bits/stdc++.h> using namespace std; using ll = long long; #define pb push_back const int N = 1e5 + 5, LOG = 17; struct HLD { vector<int> g[N]; int D[N], up[LOG][N], sz[N], pr[N], id[N], C = 0; ll a[N]; struct BIT { int n; vector<ll> b; void init(int _n) { if (n > _n) return; b.resize(_n, 0); n = _n; } void reset() { fill(b.begin(), b.end(), 0); } void add(int p, int x) { for (; p < n; p |= (p + 1)) b[p] += x; } ll sum(int r) { ll S = 0; for (; r >= 0; r = (r & (r + 1)) - 1) S += b[r]; return S; } ll sum(int l, int r) { return sum(r) - (l > 0 ? sum(l-1) : 0); } } ch[N]; void dfs(int s, int e = -1) { sz[s] = 1; for (auto u : g[s]) { if (u == e) continue; D[u] = D[s] + 1, up[0][u] = s; dfs(u, s); sz[s] += sz[u]; } for (auto u : g[s]) { if (u == e) continue; if (sz[u] > sz[s] / 2) pr[id[u]] = s, id[s] = id[u]; } if (!id[s]) { id[s] = ++C; pr[id[s]] = s; } } void dfs2(int s, int e = -1) { if (e != -1 && id[s] != id[e]) ch[id[e]].init(D[e] - D[pr[id[e]]] + 1); if (e != -1 && g[s].size() == 1) ch[id[s]].init(D[s] - D[pr[id[s]]] + 1); for (auto u : g[s]) { if (u == e) continue; dfs2(u, s); } } void init() { dfs(1); dfs2(1); for (int i = 1; i < LOG; ++i) { for (int j = 1; j < N; ++j) { up[i][j] = up[i-1][up[i-1][j]]; } } } void reset() { for (int i = 0; i < N; ++i) ch[i].reset(); fill(a, a+N, 0); } int jump(int u, int k) { for (int i = LOG-1; i >= 0; --i) { if ((k >> i) & 1) u = up[i][u]; } return u; } int lca(int u, int v) { if (D[u] < D[v]) swap(u, v); u = jump(u, D[u] - D[v]); if (u == v) return u; for (int i = LOG-1; i >= 0; --i) { if (up[i][u] != up[i][v]) u = up[i][u], v = up[i][v]; } return up[0][u]; } void add(int u, int v, ll x) { if (D[u] < D[v]) swap(u, v); if (id[u] != id[v]) a[u] += x; else { ch[id[u]].add(D[u] - D[pr[id[u]]], x); } } ll sum(int u, int v) { ll S = 0; while (D[u] > D[v]) { if (id[u] == id[v]) S += ch[id[u]].sum(D[v] - D[pr[id[u]]] + 1, D[u] - D[pr[id[u]]]); else { S += ch[id[u]].sum(0, D[u] - D[pr[id[u]]]); } u = pr[id[u]]; if (D[u] <= D[v]) break; S += a[u]; u = up[0][u]; } return S; } ll calc(int u, int v) { int L = lca(u, v); if (D[u] < D[v]) swap(u, v); return sum(u, L) + sum(v, L); } } T; int main() { ios::sync_with_stdio(0); cin.tie(0); int n, m, q; cin >> n >> m >> q; array<int, 2> E[n]; for (int i = 1; i < n; ++i) { int u, v; cin >> u >> v; T.g[u].pb(v); T.g[v].pb(u); E[i] = {u, v}; } array<int, 2> e[m+1]; for (int i = 1; i <= m; ++i) cin >> e[i][1] >> e[i][0]; sort(e+1, e+m+1); for (int i = 1; i <= m; ++i) swap(e[i][0], e[i][1]); array<int, 4> qu[q+1]; for (int i = 1; i <= q; ++i) cin >> qu[i][0] >> qu[i][1] >> qu[i][2] >> qu[i][3]; int L[q+1], R[q+1], P[q+1]; fill(L, L+q+1, 0); fill(R, R+q+1, m); fill(P, P+q+1, 0); T.init(); // for (int i = 1; i <= m; ++i) { // cout << E[e[i][0]][0] << ' ' << E[e[i][0]][1] << ' ' << e[i][1] << '\n'; // T.add(E[e[i][0]][0], E[e[i][0]][1], e[i][1]); // cout << T.calc(qu[1][0], qu[1][1]) << '\n'; // } for (int _ = 0; _ < LOG; ++_) { vector<int> B[m+1]; T.reset(); for (int i = 1; i <= q; ++i) { if (L[i] <= R[i]) { B[(L[i] + R[i]) / 2].pb(i); } } for (int i = 0; i <= m; ++i) { if (i) T.add(E[e[i][0]][0], E[e[i][0]][1], e[i][1]); for (auto j : B[i]) { if (T.calc(qu[j][0], qu[j][1]) <= qu[j][3]) P[j] = i, L[j] = i+1; else { R[j] = i-1; } } } } T.reset(); vector<int> B[m+1]; for (int i = 1; i <= q; ++i) B[P[i]].pb(i); for (int i = 0; i <= m; ++i) { if (i) T.add(E[e[i][0]][0], E[e[i][0]][1], 1); for (auto j : B[i]) { qu[j][2] += T.calc(qu[j][0], qu[j][1]); } } for (int i = 1; i <= q; ++i) { cout << max(-1LL, qu[i][2] - T.calc(qu[i][0], qu[i][1])) << '\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...