제출 #1108622

#제출 시각아이디문제언어결과실행 시간메모리
1108622jonghak9028Two Currencies (JOI23_currencies)C++17
0 / 100
17 ms24080 KiB
/* ************************************************************************** */ /* */ /* ::: ::: ::: */ /* Problem Number: 27992 :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: js9028 <boj.kr/u/js9028> +#+ +#+ +#+ */ /* +#+ +#+ +#+ */ /* https://boj.kr/27992 #+# #+# #+# */ /* Solved: 2024/11/04 23:42:53 by js9028 ### ### ##.kr */ /* */ /* ************************************************************************** */ #include <bits/stdc++.h> #define fastio (ios_base::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL)) using namespace std; typedef long long ll; const long long INF = 1e9 + 5; struct Seg { ll tree[1 << 18]; int sz = 1 << 17; void init() { memset(tree, 0, sizeof tree); } void update(int x, ll v) { x |= sz; tree[x] += v; while (x >>= 1) { tree[x] = tree[x << 1] + tree[x << 1 | 1]; } } ll query(int l, int r) { l |= sz, r |= sz; int ret = 0; while (l <= r) { if (l & 1) ret += tree[l++]; if (~r & 1) ret += tree[r--]; l >>= 1, r >>= 1; } return ret; } }; class HLD { public: int sz[101010] = {0}, dep[101010] = {0}, par[101010] = {0}, top[101010] = {0}, in[101010] = {0}, out[101010] = {0}; vector<int> g[101010]; vector<int> inp[101010]; // 입력 / 양방향 그래프 Seg seg; int chk[101010] = {0}; void dfs(int v = 1) { chk[v] = 1; for (auto i : inp[v]) { if (chk[i]) continue; chk[i] = 1; g[v].push_back(i); dfs(i); } } void dfs1(int v = 1) { sz[v] = 1; for (auto &i : g[v]) { dep[i] = dep[v] + 1; par[i] = v; dfs1(i); sz[v] += sz[i]; if (sz[i] > sz[g[v][0]]) swap(i, g[v][0]); } } int pv = 0; void dfs2(int v = 1) { in[v] = ++pv; for (auto i : g[v]) { top[i] = i == g[v][0] ? top[v] : i; dfs2(i); } out[v] = pv; } void update(int v, int w) { seg.update(in[v], w); } ll query(int a, int b) { ll ret = 0; while (top[a] ^ top[b]) { if (dep[top[a]] < dep[top[b]]) swap(a, b); int st = top[a]; ret += seg.query(in[st], in[a]); a = par[st]; } if (dep[a] > dep[b]) swap(a, b); ret += seg.query(in[a] + 1, in[b]); return ret; } }; int n, m, q; HLD hld, chld; pair<int, int> edge[101011]; vector<pair<int, int>> upe; ll X[101011], Y[101011]; ll ans[101011]; int A[101011], B[101011]; int cnt[101011]; int main() { fastio; cin >> n >> m >> q; for (int i = 1; i <= n - 1; i++) { int a, b; cin >> a >> b; hld.inp[a].push_back(b); hld.inp[b].push_back(a); chld.inp[a].push_back(b); chld.inp[b].push_back(a); edge[i] = {a, b}; } hld.dfs(); hld.dfs1(); hld.dfs2(); chld.dfs(); chld.dfs1(); chld.dfs2(); for (int i = 1; i <= n - 1; i++) { auto &p = edge[i]; if (hld.dep[p.first] < hld.dep[p.second]) swap(p.first, p.second); } for (int i = 0; i < m; i++) { int a, b; cin >> a >> b; upe.push_back({b, a}); chld.update(edge[a].first, 1); } sort(upe.begin(), upe.end()); for (int i = 0; i < q; i++) { cin >> A[i] >> B[i] >> X[i] >> Y[i]; cnt[i] = chld.query(A[i], B[i]); } vector<pair<int, int>> v(q, {0, m}); memset(ans, -1, sizeof ans); while (1) { bool f = 1; vector<int> pb[m + 1]; for (int i = 0; i < q; i++) { auto &p = v[i]; if (p.first <= p.second) { pb[(p.first + p.second) / 2].push_back(i); f = 0; } } if (f) break; hld.seg.init(); chld.seg.init(); for (int i = 0; i <= m; i++) { for (int j : pb[i]) { ll tot = hld.query(A[j], B[j]); ll nt = chld.query(A[j], B[j]); if (tot <= Y[j]) { ans[j] = X[j] - max(0ll, (cnt[j] - nt)); v[j].first = i + 1; } else { v[j].second = i - 1; } } if (i == m) continue; hld.update(edge[upe[i].second].first, upe[i].first); chld.update(edge[upe[i].second].first, 1); } } for (int i = 0; i < q; i++) { cout << (ans[i] < 0 ? -1 : ans[i]) << "\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...