Submission #823468

#TimeUsernameProblemLanguageResultExecution timeMemory
823468SUNWOOOOOOOOTwo Currencies (JOI23_currencies)C++17
100 / 100
1648 ms55716 KiB
#include <bits/stdc++.h> using namespace std; using LL = long long; using pint = pair <int, int>; const int mxN = 100005, SIZE = 200000; vector <int> adj[mxN], mid[mxN]; int n, m, q, A[mxN], B[mxN], S[mxN], T[mxN], X[mxN], ans[mxN]; LL Y[mxN]; int tin[2 * mxN], tout[2 * mxN], tcnt = 0, low[mxN], high[mxN], L[mxN]; pint C[mxN]; struct lca { int par[20][mxN], dep[mxN]; void dfs(int now, int p){ par[0][now] = p; for (int chi : adj[now]){ if (chi == p) continue; dep[chi] = dep[now] + 1; dfs(chi, now); } } void init(){ dfs(1, 1); for (int i = 1; i < 20; i++){ for (int j = 1; j <= n; j++){ par[i][j] = par[i - 1][par[i - 1][j]]; } } } int query(int x, int y){ if (dep[x] < dep[y]) swap(x, y); int dif = dep[x] - dep[y]; for (int i = 0; dif; i++){ if (dif & 1) x = par[i][x]; dif /= 2; } for (int i = 19; i >= 0; i--){ if (par[i][x] != par[i][y]){ x = par[i][x], y = par[i][y]; } } if (x == y) return x; else return par[0][x]; } } lca; struct segtree { LL node[8 * mxN]; void init(){ memset(node, 0, sizeof node); } void update(int x, int val){ for (x += 2 * n; x > 0; x /= 2) node[x] += val; } LL query(int L, int R){ LL ret = 0; for (L += 2 * n, R += 2 * n; L <= R; L /= 2, R /= 2){ if (L % 2 == 1) ret += node[L++]; if (R % 2 == 0) ret += node[R--]; } return ret; } } tree1, tree2; void euler_tour(int now, int p) { tin[now] = ++tcnt; for (int elm : adj[now]){ if (elm == p) continue; euler_tour(elm, now); } tout[now] = ++tcnt; } int main() { scanf("%d %d %d", &n, &m, &q); for (int i = 1; i <= n - 1; i++){ scanf("%d %d", &A[i], &B[i]); adj[A[i]].push_back(B[i]); adj[B[i]].push_back(A[i]); } for (int i = 1; i <= m; i++) scanf("%d %d", &C[i].second, &C[i].first); for (int i = 1; i <= q; i++) scanf("%d %d %d %lld", &S[i], &T[i], &X[i], &Y[i]); lca.init(); euler_tour(1, 1); sort(C + 1, C + m + 1); // {silver no, road no} for (int i = 1; i <= q; i++){low[i] = 0, high[i] = m;} for (int i = 1; i <= q; i++){ L[i] = lca.query(S[i], T[i]); } for (int i = 1; i <= n - 1; i++){ if (lca.dep[A[i]] < lca.dep[B[i]]) swap(A[i], B[i]); } memset(ans, -1, sizeof ans); while (1){ tree1.init(); tree2.init(); for (int i = 0; i <= m; i++) mid[i].clear(); bool endflag = true; for (int i = 1; i <= q; i++){ if (low[i] <= high[i]){ endflag = false; mid[(low[i] + high[i]) / 2].push_back(i); } } if (endflag) break; for (int i = 0; i <= m; i++){ for (int j : mid[i]){ // ansi = maximum no of gold replaced by silver LL ysum = tree2.query(1, tin[T[j]]) + tree2.query(1, tin[S[j]]) - 2 * tree2.query(1, tin[L[j]]); if (ysum <= Y[j]){ ans[j] = tree1.query(1, tin[T[j]]) + tree1.query(1, tin[S[j]]) - 2 * tree1.query(1, tin[L[j]]); low[j] = i + 1; } else { high[j] = i - 1; } } if (i == m) continue; int a = A[C[i + 1].second], val = C[i + 1].first; tree1.update(tin[a], 1); tree1.update(tout[a], -1); tree2.update(tin[a], val); tree2.update(tout[a], -val); } } tree1.init(); for (int i = 1; i <= m; i++){ int a = A[C[i].second], val = C[i].first; tree1.update(tin[a], 1); tree1.update(tout[a], -1); } for (int i = 1; i <= q; i++) { int gsum = tree1.query(1, tin[T[i]]) + tree1.query(1, tin[S[i]]) - 2 * tree1.query(1, tin[L[i]]); if (X[i] + ans[i] >= gsum) printf("%d\n", max(0, X[i] + ans[i] - gsum)); else printf("-1\n"); } return 0; }

Compilation message (stderr)

currencies.cpp: In function 'int main()':
currencies.cpp:133:33: warning: unused variable 'val' [-Wunused-variable]
  133 |         int a = A[C[i].second], val = C[i].first;
      |                                 ^~~
currencies.cpp:76:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   76 |     scanf("%d %d %d", &n, &m, &q);
      |     ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
currencies.cpp:78:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   78 |         scanf("%d %d", &A[i], &B[i]);
      |         ~~~~~^~~~~~~~~~~~~~~~~~~~~~~
currencies.cpp:82:39: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   82 |     for (int i = 1; i <= m; i++) scanf("%d %d", &C[i].second, &C[i].first);
      |                                  ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
currencies.cpp:83:39: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   83 |     for (int i = 1; i <= q; i++) scanf("%d %d %d %lld", &S[i], &T[i], &X[i], &Y[i]);
      |                                  ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...