Submission #893273

#TimeUsernameProblemLanguageResultExecution timeMemory
893273ksujay2Two Currencies (JOI23_currencies)C++17
100 / 100
4265 ms33224 KiB
#include <bits/stdc++.h> using namespace std; using ll = long long; int lg(unsigned long long i) { return i ? __builtin_clzll(1) - __builtin_clzll(i) : -1; } struct BIT { vector<ll> tree; BIT(int n) { tree = vector<ll>(n + 1); } ll sum(int k) { ll s = 0; while(k >= 1) s += tree[k], k -= k&-k; return s; } void add(int k, ll x) { while (k < (int)tree.size()) tree[k] += x, k += k&-k; } int lb(ll x) { ll s = 0, p = 0; for(int i = lg(tree.size()); i >= 0; i--) if(p + (1 << i) < tree.size() && s + tree[p + (1 << i)] <= x) p += (1 << i), s += tree[p]; return p; } }; struct Edge { int a, b; vector<int> c; }; struct Query { int S, E, i; ll s; }; const int BS = 450; int main() { ios::sync_with_stdio(false), cin.tie(nullptr); int N, M, Q; cin >> N >> M >> Q; vector<Edge> edge(N - 1); vector<vector<int>> inc(N); for(int i = 0; i < N - 1; i++) { cin >> edge[i].a >> edge[i].b; edge[i].a--, edge[i].b--; inc[edge[i].a].push_back(i); inc[edge[i].b].push_back(i); } vector<pair<ll, int>> cp(M); for(int i = 0; i < M; i++) { cin >> cp[i].second >> cp[i].first; cp[i].second--; } sort(cp.begin(), cp.end()); for(int i = 0; i < M; i++) { edge[cp[i].second].c.push_back(i); } vector<int> in(N); vector<int> o; function<void(int, int)> dfs = [&] (int s, int e) { in[s] = o.size(); for(int ei : inc[s]) { int u = (edge[ei].a == s) ? edge[ei].b : edge[ei].a; if(u != e) { for(int c : edge[ei].c) o.push_back(c); dfs(u, s); for(int c : edge[ei].c) o.push_back(c); } } }; dfs(0, -1); vector<Query> queries(Q); vector<int> gold(Q); for(int i = 0; i < Q; i++) { int a, b; cin >> a >> b >> gold[i] >> queries[i].s; a--, b--; if(in[a] > in[b]) swap(a, b); queries[i].S = in[a]; queries[i].E = in[b]; queries[i].i = i; } sort(queries.begin(), queries.end(), [&] (Query a, Query b) { return (a.S / BS == b.S / BS) ? (a.E < b.E) : (a.S / BS < b.S / BS); }); vector<int> ans(Q); vector<int> active(M); BIT smbit(M); BIT actbit(M); int totalact = 0; auto toggle = [&] (int x) { if(active[x]) { actbit.add(x + 1, -1); smbit.add(x + 1, -cp[x].first); totalact--; } else { actbit.add(x + 1, 1); smbit.add(x + 1, cp[x].first); totalact++; } active[x] ^= 1; }; int L = 0, R = 0; for(int i = 0; i < Q; i++) { while(L < queries[i].S) { toggle(o[L++]); } while(R < queries[i].E) { toggle(o[R++]); } while(L > queries[i].S) { toggle(o[--L]); } while(R > queries[i].E) { toggle(o[--R]); } ans[queries[i].i] = totalact - actbit.sum(smbit.lb(queries[i].s)); } for(int i = 0; i < Q; i++) { if(gold[i] < ans[i]) cout << -1 << '\n'; else cout << gold[i] - ans[i] << '\n'; } }

Compilation message (stderr)

currencies.cpp: In member function 'int BIT::lb(ll)':
currencies.cpp:14:29: warning: comparison of integer expressions of different signedness: 'll' {aka 'long long int'} and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   14 |             if(p + (1 << i) < tree.size() && s + tree[p + (1 << i)] <= x)
      |                ~~~~~~~~~~~~~^~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...