Submission #729015

#TimeUsernameProblemLanguageResultExecution timeMemory
729015MilosMilutinovicTwo Currencies (JOI23_currencies)C++14
100 / 100
4624 ms93864 KiB
/** * author: wxhtzdy * created: 19.03.2023 07:01:27 **/ #include <bits/stdc++.h> using namespace std; const int N = 100010; const int L = 18; const int M = N * 32; const int inf = (int) 1e9 + 1; int rt[N], cs[N], tsz, ls[M], rs[M], cnt[M]; long long sum[M]; vector<int> g[N]; int pr[N][L]; int x[N], y[N], dep[N]; void Modify(int& v, int p, int l, int r, int x, int d) { v = ++tsz; ls[v] = ls[p]; rs[v] = rs[p]; cnt[v] = cnt[p] + d; sum[v] = sum[p] + x * d; if (l == r) { return; } int mid = l + r >> 1; if (x <= mid) { Modify(ls[v], ls[p], l, mid, x, d); } else { Modify(rs[v], rs[p], mid + 1, r, x, d); } } int GetCnt(int v, int l, int r, int ql, int qr) { if (!v || l > r || ql > qr || l > qr || r < ql) { return 0; } if (ql <= l && r <= qr) { return cnt[v]; } int mid = l + r >> 1; return GetCnt(ls[v], l, mid, ql, qr) + GetCnt(rs[v], mid + 1, r, ql, qr); } long long GetSum(int v, int l, int r, int ql, int qr) { if (!v || l > r || ql > qr || l > qr || r < ql) { return 0LL; } if (ql <= l && r <= qr) { return sum[v]; } int mid = l + r >> 1; return GetSum(ls[v], l, mid, ql, qr) + GetSum(rs[v], mid + 1, r, ql, qr); } int FindFirst(int v0, int v1, int v2, int l, int r, int x) { if (l == r) { return l; } int mid = l + r >> 1; int L = cnt[ls[v0]] + cnt[ls[v1]] - 2 * cnt[ls[v2]]; if (L >= x) { return FindFirst(ls[v0], ls[v1], ls[v2], l, mid, x); } else { return FindFirst(rs[v0], rs[v1], rs[v2], mid + 1, r, x - L); } } void Go(int v, int pv) { for (int u : g[v]) { if (u == pv) { continue; } dep[u] = dep[v] + 1; Go(u, v); } } vector<int> qs[N]; void Dfs(int v, int pv) { pr[v][0] = pv; for (int j = 1; j < L; j++) { pr[v][j] = pr[pr[v][j - 1]][j - 1]; } for (int c : qs[v]) { Modify(rt[v], rt[v], 1, inf, c, +1); cs[v] += 1; } for (int u : g[v]) { if (u == pv) { continue; } rt[u] = rt[v]; cs[u] = cs[v]; Dfs(u, v); } } int LCA(int x, int y) { if (dep[x] > dep[y]) { swap(x, y); } for (int j = L - 1; j >= 0; j--) { if (dep[pr[y][j]] >= dep[x]) { y = pr[y][j]; } } for (int j = L - 1; j >= 0; j--) { if (pr[x][j] != pr[y][j]) { x = pr[x][j]; y = pr[y][j]; } } return (x == y ? x : pr[x][0]); } long long Get(int s, int t, int w, int f) { int p = FindFirst(rt[s], rt[t], rt[w], 1, inf, f); int cc = GetCnt(rt[s], 1, inf, 1, p - 1) + GetCnt(rt[t], 1, inf, 1, p - 1) - 2 * GetCnt(rt[w], 1, inf, 1, p - 1); long long res = GetSum(rt[s], 1, inf, 1, p - 1) + GetSum(rt[t], 1, inf, 1, p - 1) - 2 * GetSum(rt[w], 1, inf, 1, p - 1); res += p * 1LL * (f - cc); return res; } int main() { ios::sync_with_stdio(false); cin.tie(0); int n, m, q; cin >> n >> m >> q; for (int i = 1; i < n; i++) { cin >> x[i] >> y[i]; --x[i]; --y[i]; g[x[i]].push_back(y[i]); g[y[i]].push_back(x[i]); } Go(0, 0); for (int i = 1; i < n; i++) { if (dep[x[i]] > dep[y[i]]) { swap(x[i], y[i]); } } for (int i = 0; i < m; i++) { int p, c; cin >> p >> c; qs[y[p]].push_back(c); } Dfs(0, 0); while (q--) { int s, t, a; long long b; cin >> s >> t >> a >> b; --s; --t; int w = LCA(s, t); int f = cs[s] + cs[t] - 2 * cs[w]; int low = 0, high = a, ans = -1; while (low <= high) { int mid = low + high >> 1; if (Get(s, t, w, max(0, f - (a - mid))) <= b) { ans = mid; low = mid + 1; } else { high = mid - 1; } } cout << ans << '\n'; } return 0; }

Compilation message (stderr)

currencies.cpp: In function 'void Modify(int&, int, int, int, int, int)':
currencies.cpp:29:15: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   29 |   int mid = l + r >> 1;
      |             ~~^~~
currencies.cpp: In function 'int GetCnt(int, int, int, int, int)':
currencies.cpp:44:15: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   44 |   int mid = l + r >> 1;
      |             ~~^~~
currencies.cpp: In function 'long long int GetSum(int, int, int, int, int)':
currencies.cpp:55:15: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   55 |   int mid = l + r >> 1;
      |             ~~^~~
currencies.cpp: In function 'int FindFirst(int, int, int, int, int, int)':
currencies.cpp:63:15: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   63 |   int mid = l + r >> 1;
      |             ~~^~~
currencies.cpp: In function 'int main()':
currencies.cpp:164:21: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  164 |       int mid = low + high >> 1;
      |                 ~~~~^~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...