제출 #1037262

#제출 시각아이디문제언어결과실행 시간메모리
10372620npataTwo Currencies (JOI23_currencies)C++17
100 / 100
2913 ms540796 KiB
using namespace std; #include<bits/stdc++.h> const int MXN = 1e5 + 5; const int MXM = 1e5 + 5; #define int long long struct Node { using ptr = shared_ptr<Node>; ptr left, right; int sum = 0; int cnt = 0; Node() = default; Node(int sum, int cnt, ptr left = nullptr, ptr right = nullptr) : sum(sum), cnt(cnt), left(left), right(right) {} ptr get_left() { if (!left) left = make_shared<Node>(); return left; } ptr get_right() { if (!right) right = make_shared<Node>(); return right; } ptr update(int l, int r, int add, int tl = 0, int tr = MXN) { if (tl >= r || tr <= l) return make_shared<Node>(sum, cnt, left, right); if (tl >= l && tr <= r) return make_shared<Node>(sum + add, cnt + 1, left, right); int tm = (tl + tr) / 2; return make_shared<Node>( sum, cnt, get_left()->update(l, r, add, tl, tm), get_right()->update(l, r, add, tm, tr) ); } pair<int, int> query(int i, int tl = 0, int tr = MXN) const { if (tl + 1 == tr) return {sum, cnt}; int tm = (tl + tr) / 2; if (i < tm) { if (!left) return {sum, cnt}; auto res = left->query(i, tl, tm); return {res.first + sum, res.second + cnt}; } else { if (!right) return {sum, cnt}; auto res = right->query(i, tm, tr); return {res.first + sum, res.second + cnt}; } } }; Node::ptr pers_st[MXM]; int in[MXN], out[MXN], depth[MXN], jmp[MXN][20]; vector<int> tree[MXN]; int t = 0; void dfs1(int u, int p = -1) { jmp[u][0] = p; for (int i = 1; i < 20; i++) { if (jmp[u][i - 1] == -1) { jmp[u][i] = -1; continue; } jmp[u][i] = jmp[jmp[u][i - 1]][i - 1]; } in[u] = t++; for (int v : tree[u]) { if (v == p) continue; depth[v] = depth[u] + 1; dfs1(v, u); } out[u] = t; } int lca(int u, int v) { if (depth[u] < depth[v]) swap(u, v); for (int i = 0; i < 20; i++) { if ((depth[u] - depth[v]) & (1 << i)) { u = jmp[u][i]; } } if (u == v) return u; for (int i = 19; i >= 0; i--) { if (jmp[u][i] != jmp[v][i]) { u = jmp[u][i]; v = jmp[v][i]; } } return jmp[u][0]; } int32_t main() { ios_base::sync_with_stdio(false); cin.tie(0); int N, M, Q; cin >> N >> M >> Q; vector<pair<int, int>> edges(N - 1); for (int i = 0; i < N - 1; i++) { int u, v; cin >> u >> v; u--; v--; tree[u].push_back(v); tree[v].push_back(u); edges[i] = {u, v}; } dfs1(0); vector<pair<int, int>> cs(M); for (int i = 0; i < M; i++) { int ei, c; cin >> ei >> c; ei--; cs[i] = {c, ei}; } sort(cs.begin(), cs.end()); pers_st[0] = make_shared<Node>(); for (int i = 1; i <= M; i++) { auto [c, ei] = cs[i - 1]; auto [u, v] = edges[ei]; if (depth[u] < depth[v]) swap(u, v); pers_st[i] = pers_st[i - 1]->update(in[u], out[u], c); } for (int i = 0; i < Q; i++) { int u, v, g, s; cin >> u >> v >> g >> s; u--; v--; int w = lca(u, v); auto eval = [&](int k) { auto [a1, a2] = pers_st[k]->query(in[u]); auto [b1, b2] = pers_st[k]->query(in[v]); auto [c1, c2] = pers_st[k]->query(in[w]); return pair<int, int>{a1 + b1 - 2 * c1, a2 + b2 - 2 * c2}; }; int l = 0; int r = M + 1; while (l + 1 < r) { int m = (l + r) / 2; auto res = eval(m); if (res.first > s) { r = m; } else { l = m; } } int cnt = eval(l).second; int tot_cnt = eval(M).second; if (tot_cnt - cnt > g) { cout << -1 << '\n'; } else { cout << g - (tot_cnt - cnt) << '\n'; } } return 0; }

컴파일 시 표준 에러 (stderr) 메시지

currencies.cpp: In constructor 'Node::Node(long long int, long long int, Node::ptr, Node::ptr)':
currencies.cpp:14:9: warning: 'Node::cnt' will be initialized after [-Wreorder]
   14 |     int cnt = 0;
      |         ^~~
currencies.cpp:12:9: warning:   'Node::ptr Node::left' [-Wreorder]
   12 |     ptr left, right;
      |         ^~~~
currencies.cpp:18:5: warning:   when initialized here [-Wreorder]
   18 |     Node(int sum, int cnt, ptr left = nullptr, ptr right = nullptr)
      |     ^~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...