Submission #943993

#TimeUsernameProblemLanguageResultExecution timeMemory
943993becaidoTwo Currencies (JOI23_currencies)C++17
100 / 100
1582 ms91988 KiB
#pragma GCC optimize("O3,unroll-loops") #pragma GCC target("avx,popcnt,sse4,abm") #include <bits/stdc++.h> using namespace std; #ifdef WAIMAI #define debug(HEHE...) cout << "[" << #HEHE << "] : ", dout(HEHE) void dout() {cout << '\n';} template<typename T, typename...U> void dout(T t, U...u) {cout << t << (sizeof...(u) ? ", " : ""), dout(u...);} #else #define debug(...) 7122 #endif #define ll long long #define Waimai ios::sync_with_stdio(false), cin.tie(0) #define FOR(x,a,b) for (int x = a, I = b; x <= I; x++) #define pb emplace_back #define F first #define S second const int SIZE = 2e5 + 5; const int TSIZ = (__lg(SIZE) + 4) * SIZE; int n, m, q; pair<int, int> a[SIZE]; vector<int> adj[SIZE], op[SIZE]; struct Node { int cnt, ls, rs; ll sum; Node() {} Node(int cnt, ll sum) : cnt(cnt), sum(sum), ls(0), rs(0) {} Node operator + (const Node &o) const { return Node(cnt + o.cnt, sum + o.sum); } Node operator - (const Node &o) const { return Node(cnt - o.cnt, sum - o.sum); } } node[TSIZ]; int sz, root[SIZE]; void upd(int &pos, int l, int r, int p) { node[++sz] = node[pos]; pos = sz; node[pos].cnt++; node[pos].sum += a[p].F; if (l == r) return; int mid = (l + r) / 2; if (p <= mid) upd(node[pos].ls, l, mid, p); else upd(node[pos].rs, mid + 1, r, p); } Node que(int tl, int tr, int l, int r, int L, int R) { if (l == L && r == R) return node[tr] - node[tl]; int mid = (L + R) / 2; Node &nl = node[tl], &nr = node[tr]; if (r <= mid) return que(nl.ls, nr.ls, l, r, L, mid); if (l > mid) return que(nl.rs, nr.rs, l, r, mid + 1, R); return que(nl.ls, nr.ls, l, mid, L, mid) + que(nl.rs, nr.rs, mid + 1, r, mid + 1, R); } int w[SIZE], son[SIZE], dep[SIZE], pa[SIZE], top[SIZE]; void dfs1(int pos) { w[pos] = 1; for (int np : adj[pos]) if (np != pa[pos]) { dep[np] = dep[pos] + 1; pa[np] = pos; dfs1(np); w[pos] += w[np]; if (w[np] > w[son[pos]]) son[pos] = np; } } void dfs2(int pos) { if (top[pos] != 0) root[pos] = root[pa[pos]]; else top[pos] = pos; for (int i : op[pos]) upd(root[pos], 1, m, i); if (son[pos]) { top[son[pos]] = top[pos]; dfs2(son[pos]); } for (int np : adj[pos]) if (np != pa[pos] && np != son[pos]) { dfs2(np); } } int que_cnt(int a, int b) { int cnt = 0; while (true) { if (top[a] == top[b]) { if (dep[a] > dep[b]) swap(a, b); int tl = (a == top[a] ? 0 : root[pa[a]]), tr = root[b]; cnt += node[tr].cnt - node[tl].cnt; break; } if (dep[top[a]] < dep[top[b]]) swap(a, b); cnt += node[root[a]].cnt; a = pa[top[a]]; } return cnt; } int cal(int r, int a, int b, ll lim) { if (r == 0) return 0; int cnt = 0; ll sum = 0; while (sum <= lim) { if (top[a] == top[b]) { if (dep[a] > dep[b]) swap(a, b); int tl = (a == top[a] ? 0 : root[pa[a]]), tr = root[b]; Node nd = que(tl, tr, 1, r, 1, m); cnt += nd.cnt, sum += nd.sum; break; } if (dep[top[a]] < dep[top[b]]) swap(a, b); Node nd = que(0, root[a], 1, r, 1, m); cnt += nd.cnt, sum += nd.sum; a = pa[top[a]]; } if (sum > lim) return -1; return cnt; } void solve() { cin >> n >> m >> q; FOR (i, 1, n - 1) { int a, b; cin >> a >> b; adj[a].pb(n + i), adj[n + i].pb(a); adj[b].pb(n + i), adj[n + i].pb(b); } FOR (i, 1, m) { auto &[val, p] = a[i]; cin >> p >> val; p += n; } sort(a + 1, a + m + 1); FOR (i, 1, m) op[a[i].S].pb(i); dep[1] = 1, dfs1(1), dfs2(1); while (q--) { int a, b, x; ll y; cin >> a >> b >> x >> y; int l = 0, r = m, k = que_cnt(a, b); while (l < r) { int mid = (l + r) / 2 + 1; if (cal(mid, a, b, y) >= 0) l = mid; else r = mid - 1; } int d = cal(l, a, b, y); if (x < k - d) cout << "-1\n"; else cout << x - (k - d) << '\n'; } } int main() { Waimai; solve(); }

Compilation message (stderr)

currencies.cpp: In constructor 'Node::Node(int, long long int)':
currencies.cpp:31:8: warning: 'Node::sum' will be initialized after [-Wreorder]
   31 |     ll sum;
      |        ^~~
currencies.cpp:30:14: warning:   'int Node::ls' [-Wreorder]
   30 |     int cnt, ls, rs;
      |              ^~
currencies.cpp:33:5: warning:   when initialized here [-Wreorder]
   33 |     Node(int cnt, ll sum) : cnt(cnt), sum(sum), ls(0), rs(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...