Submission #1304247

#TimeUsernameProblemLanguageResultExecution timeMemory
1304247KietJTwo Currencies (JOI23_currencies)C++17
100 / 100
2862 ms42772 KiB
#include <bits/stdc++.h> using namespace std; #define file "bai4" //#define int long long #define ll long long #define pii pair<int, int> #define fi first #define se second #define pb push_back #define sz(a) (int)a.size() #define mask(i) (1 << i) const int N = 1e5, inf = 1e9, K = __lg(N); void MAX(int &a, int b) { a = max(a, b); } void MIN(int &a, int b) { a = min(a, b); } int n, m, q, curchain, Time; int h[N + 2], up[N + 2][K + 2], lg[N + 2], ans[N + 2], cnt[N + 2], in[N + 2], ID[N + 2], head[N + 2], sz[N + 2], par[N + 2], s[N + 2], t[N + 2], L[N + 2], R[N + 2]; bool ok[N + 2]; ll dp[N + 2], all[N + 2], fw[N + 2], X[N + 2], Y[N + 2], sum[N + 2], remain[N + 2]; vector<int> g[N + 2], val[N + 2]; vector<pii> ed, smt[N + 2]; void dfs(int u, int p) { h[u] = h[p] + 1; sz[u] = 1; for (int v : g[u]) if (v != p) { up[v][0] = u; for (int j = 1; j <= K; j++) { if (up[v][j - 1] == 0) break; up[v][j] = up[up[v][j - 1]][j - 1]; } dfs(v, u); sz[u] += sz[v]; } } void hld(int u, int p) { if (head[curchain] == 0) head[curchain] = u; ID[u] = curchain; in[u] = ++Time; par[u] = p; int big = 0; for (int v : g[u]) if (v != p && sz[v] > sz[big]) big = v; if (big > 0) hld(big, u); for (int v : g[u]) if (v != p && v != big) { curchain++; hld(v, u); } } void dfs2(int u, int p) { for (int v : g[u]) if (v != p) dp[v] += dp[u], dfs2(v, u); } int upk(int u, int k) { for (int j = 0; mask(j) <= k; j++) if (k & mask(j)) u = up[u][j]; return u; } void lca(int u, int v, int id) { if (h[u] < h[v]) swap(u, v); int U = u, V = v; int k = h[u] - h[v]; u = upk(u, k); if (u == v) { int w = u; u = U; v = V; if (v == w) swap(u, v); all[id] = dp[v] - dp[w]; u = upk(v, h[v] - h[w] - 1); smt[id].pb({v, u}); } else { k = lg[h[u]]; for (int j = k; j >= 0; j--) if (up[u][j] != up[v][j]) u = up[u][j], v = up[v][j]; smt[id].pb({U, u}); smt[id].pb({V, v}); u = up[u][0]; all[id] = dp[U] + dp[V] - 2 * dp[u]; } } void update(int u, int x) { while (u <= n) fw[u] += x, u += u & -u; } ll get(int u) { ll ans = 0; while (u > 0) ans += fw[u], u -= u & -u; return ans; } ll GET(int l, int r) { return get(r) - get(l - 1); } ll getpath(int u, int v) { ll res = 0; while (ID[u] > ID[v]) { res += GET(in[head[ID[u]]], in[u]); u = par[head[ID[u]]]; } res += GET(in[v], in[u]); return res; } ll getqry(int id) { ll res = 0; for (pii &x : smt[id]) res += getpath(x.fi, x.se); return res; } int lcaslow(int u, int v, int id) { ll sum = 0; vector<int> cur; if (h[u] < h[v]) swap(u, v); while (h[u] > h[v]) { for (int x : val[u]) cur.pb(x), sum += x; u = up[u][0]; } while (u != v) { for (int x : val[u]) cur.pb(x), sum += x; for (int x : val[v]) cur.pb(x), sum += x; u = up[u][0]; v = up[v][0]; } sort(cur.begin(), cur.end(), greater<int>()); if (sum <= Y[id]) return X[id]; for (int i = 0; i < sz(cur); i++) { if (i + 1 > X[id]) break; sum -= cur[i]; if (sum <= Y[id]) return X[id] - (i + 1); } return -1; } void Sub1(vector<pii> &f) { for (int i = 1; i <= m; i++) { int id, x; cin >> id >> x; id--; if (h[f[id].fi] > h[f[id].se]) val[f[id].fi].pb(x); else val[f[id].se].pb(x); } for (int i = 1; i <= q; i++) { cin >> s[i] >> t[i] >> X[i] >> Y[i]; cout << lcaslow(s[i], t[i], i) << "\n"; } } signed main() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); if (fopen(file".inp", "r")) { freopen(file".inp", "r", stdin); freopen(file".out", "w", stdout); } cin >> n >> m >> q; vector<pii> f; for (int i = 1; i < n; i++) { int u, v; cin >> u >> v; f.pb({u, v}); g[u].pb(v); g[v].pb(u); } for (int i = 2; i <= n; i++) lg[i] = lg[i / 2] + 1; dfs(1, 0); // if (max({n, m, q}) <= 2e3) return Sub1(f), 0; hld(1, 0); for (int i = 1; i <= m; i++) { int id, x; cin >> id >> x; pii cur; cur.fi = x; id--; if (h[f[id].fi] > h[f[id].se]) cur.se = f[id].fi; else cur.se = f[id].se; dp[cur.se] += x; ed.pb(cur); } dfs2(1, 0); for (int i = 1; i <= q; i++) { cin >> s[i] >> t[i] >> X[i] >> Y[i]; L[i] = 1; R[i] = inf + 1; lca(s[i], t[i], i); } sort(ed.begin(), ed.end(), greater<pii>()); // for (pii &f : ed) cout << f.fi << " " << f.se << "\n"; bool run = 1; while (run) { run = 0; vector<pii> qry; for (int i = 1; i <= q; i++) if (L[i] <= R[i]) { qry.pb({(L[i] + R[i]) / 2, i}); run = 1; } sort(qry.begin(), qry.end(), greater<pii>()); for (int i = 1; i <= n; i++) fw[i] = 0; int pos = 0; for (pii &f : qry) { int id = f.se; while (pos < sz(ed) && ed[pos].fi >= f.fi) { update(in[ed[pos].se], ed[pos].fi); pos++; } ll cur = getqry(id); if (all[id] - cur <= Y[id]) { ok[id] = 1; sum[id] = cur; remain[id] = all[id] - cur; } else ok[id] = 0; } for (int i = 1; i <= q; i++) if (L[i] <= R[i]) { if (ok[i]) { ans[i] = (L[i] + R[i]) / 2; L[i] = (L[i] + R[i]) / 2 + 1; } else R[i] = (L[i] + R[i]) / 2 - 1; } } vector<pii> qry; for (int i = 1; i <= q; i++) qry.pb({ans[i], i}); sort(qry.begin(), qry.end(), greater<pii>()); for (int i = 1; i <= n; i++) fw[i] = 0; int pos = 0; for (pii &f : qry) { int id = f.se; while (pos < sz(ed) && ed[pos].fi >= f.fi) { update(in[ed[pos].se], 1); pos++; } ll cur = getqry(id); cnt[id] = cur; } for (int i = 1; i <= q; i++) { ll delta = (Y[i] - remain[i]) / ans[i]; if (delta >= cnt[i]) cout << X[i] << "\n"; else { cnt[i] -= delta; if (cnt[i] > X[i]) cout << -1 << "\n"; else cout << X[i] - cnt[i] << "\n"; } } }

Compilation message (stderr)

currencies.cpp: In function 'int main()':
currencies.cpp:174:12: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  174 |     freopen(file".inp", "r", stdin);
      |     ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
currencies.cpp:175:12: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  175 |     freopen(file".out", "w", stdout);
      |     ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...