Submission #1253243

#TimeUsernameProblemLanguageResultExecution timeMemory
1253243Peter2017Two Currencies (JOI23_currencies)C++20
0 / 100
4 ms5448 KiB
#include <bits/stdc++.h> #define fi first #define se second #define ll long long #define pii pair<int,int> #define pll pair<ll,ll> #define pill pair<int,ll> #define mem(a, b) memset(a, b, sizeof(a)) #define MASK(i) (1LL << (i)) #define BIT(x, i) (((x) >> (i)) & 1) #define name "test" using namespace std; const int N = 1e5 + 5; const int LOG = 31 - __builtin_clz(N); template <typename T1, typename T2> bool maxi(T1 &a, T2 b){if (a < b){a = b; return 1;} return 0;} template <typename T1, typename T2> bool mini(T1 &a, T2 b){if (a > b){a = b; return 1;} return 0;} struct item { int u, v, gold_coin; long long silver_coin; void input(){ cin >> u >> v >> gold_coin >> silver_coin; } }; struct FenwickTree{ int n; int cnt[N]; long long val[N]; FenwickTree(){} void reset(){ for (int i = 1; i <= n; i++) val[i] = cnt[i] = 0; } void update(int idx, int x){ assert(idx > 0); for (; idx <= n; idx += idx & -idx){ val[idx] += x; cnt[idx] += (x < 0 ? -1 : 1); } } pair<long long, int> get(int idx){ int s_cnt = 0; long long sum = 0; for (; idx; idx -= idx & -idx){ sum += val[idx]; s_cnt += cnt[idx]; } return {sum, s_cnt}; } } ft; int n; int m; int q; int st[N]; int ed[N]; int rep[N]; int ans[N]; int L[N], R[N]; int high[N]; int par[N][LOG + 1]; item query[N]; pii edges[N]; pii checkpoint[N]; vector<int> adj[N]; vector<int> query_list[N]; void load(){ cin.tie(0)->sync_with_stdio(0); if (fopen(name".inp", "r")){ freopen(name".inp", "r", stdin); freopen(name".out", "w", stdout); } } void input(){ cin >> n >> m >> q; for (int i = 1; i < n; i++){ int u, v; cin >> u >> v; adj[u].push_back(i); adj[v].push_back(i); edges[i] = {u, v}; } for (int i = 1; i <= m; i++){ cin >> checkpoint[i].fi >> checkpoint[i].se; } for (int i = 1; i <= q; i++){ query[i].input(); L[i] = 0; R[i] = m; } } void dfs_euler(int u, int pre){ static int cntDfs = 0; st[u] = ++cntDfs; for (int idx : adj[u]){ int v = edges[idx].fi + edges[idx].se - u; if (v != pre){ rep[idx] = v; par[v][0] = u; high[v] = high[u] + 1; dfs_euler(v, u); } } ed[u] = cntDfs; } bool cmp(pii x, pii y){ return x.se < y.se; } int LCA(int u, int v){ if (high[u] < high[v]) swap(u, v); for (int j = LOG; j >= 0; j--) if (high[par[u][j]] >= high[v]) u = par[u][j]; if (u == v) return u; for (int j = LOG; j >= 0; j--) if (par[u][j] != par[v][j]){ u = par[u][j]; v = par[v][j]; } return par[u][0]; } void solve(){ mem(ans, -1); dfs_euler(1, 0); sort(checkpoint + 1, checkpoint + m + 1, cmp); for (int j = 1; j <= LOG; j++) for (int i = 1; i <= n; i++) par[i][j] = par[par[i][j - 1]][j - 1]; high[0] = -1; // for (int i = 1; i <= m; i++) cout << checkpoint[i].fi << ' ' << checkpoint[i].se << '\n'; ft.n = n; int kkk = 0; bool processing = 1; while (processing){ processing = 0; for (int i = 1; i <= q; i++){ if (L[i] <= R[i]){ processing = 1; int m = (L[i] + R[i]) / 2; query_list[m].push_back(i); } } ft.reset(); for (int i = 0; i <= m; i++){ if (i){ ft.update(st[rep[checkpoint[i].fi]], checkpoint[i].se); ft.update(ed[rep[checkpoint[i].fi]] + 1, -checkpoint[i].se); } for (int j : query_list[i]){ auto [u, v, gold_coin, silver_coin] = query[j]; int ancestor = LCA(u, v); pair<long long, int> tmp1 = ft.get(st[u]); pair<long long, int> tmp2 = ft.get(st[v]); pair<long long, int> tmp3 = ft.get(st[ancestor]); if (tmp1.fi + tmp2.fi - tmp3.fi * 2 <= silver_coin){ ans[j] = tmp1.se + tmp2.se - tmp3.se * 2; L[j] = i + 1; } else R[j] = i - 1; } query_list[i].clear(); } } ft.reset(); for (int i = 1; i <= m; i++){ ft.update(st[rep[checkpoint[i].fi]], checkpoint[i].se); ft.update(ed[rep[checkpoint[i].fi]] + 1, -checkpoint[i].se); } for (int i = 1; i <= q; i++){ if (ans[i] == -1) cout << -1 << '\n'; else { auto [u, v, gold_coin, silver_coin] = query[i]; int ancestor = LCA(u, v); pair<long long, int> tmp1 = ft.get(st[u]); pair<long long, int> tmp2 = ft.get(st[v]); pair<long long, int> tmp3 = ft.get(st[ancestor]); int tmp = tmp1.se + tmp2.se - tmp3.se * 3 - ans[i]; if (tmp <= gold_coin) cout << tmp << '\n'; else cout << -1 << '\n'; } } } int main(){ load(); input(); solve(); }

Compilation message (stderr)

currencies.cpp: In function 'void load()':
currencies.cpp:80:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
   80 |         freopen(name".inp", "r", stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
currencies.cpp:81:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
   81 |         freopen(name".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...