Submission #942415

#TimeUsernameProblemLanguageResultExecution timeMemory
942415LOLOLOTwo Currencies (JOI23_currencies)C++17
100 / 100
987 ms89132 KiB
#include <bits/stdc++.h> #define ll long long using namespace std; #define f first #define s second #define pb push_back #define ep emplace #define eb emplace_back #define lb lower_bound #define ub upper_bound #define all(x) x.begin(), x.end() #define rall(x) x.rbegin(), x.rend() #define uniquev(v) sort(all(v)), (v).resize(unique(all(v)) - (v).begin()) #define mem(f,x) memset(f , x , sizeof(f)) #define sz(x) (int)(x).size() #define __lcm(a, b) (1ll * ((a) / __gcd((a), (b))) * (b)) #define mxx *max_element #define mnn *min_element #define cntbit(x) __builtin_popcountll(x) #define len(x) (int)(x.length()) const int N = 3e5; vector <pair <int, int>> ed[N]; int p[N][20], in[N], ou[N], timer = 1, f[N], id[N], val[N], ans[N], cnt[N]; struct fen{ vector <ll> f; int N; void ass(int n) { N = n; f.assign(n + 1, 0); } void upd(int i, int x) { for (; i <= N; i += i & (-i)) f[i] += x; } ll get(int u) { ll s = 0; for (; u; u -= u & (-u)) s += f[u]; return s; } void range(int l, int r, int x) { upd(l, x); upd(r + 1, -x); } } f1, f2; void dfs(int u, int v) { timer++; in[u] = timer; p[u][0] = v; for (int i = 1; i < 20; i++) p[u][i] = p[p[u][i - 1]][i - 1]; for (auto x : ed[u]) { if (x.f == v) continue; id[x.s] = x.f; dfs(x.f, u); } ou[u] = timer; } bool is(int a, int b) { return in[a] <= in[b] && ou[a] >= ou[b]; } int lca(int a, int b) { if (is(a, b)) return a; if (is(b, a)) return b; for (int i = 19; i >= 0; i--) { if (is(p[a][i], b) == 0) a = p[a][i]; } return p[a][0]; } ll sum(int s, int e, fen &f) { int c = lca(s, e); return f.get(in[s]) + f.get(in[e]) - 2 * f.get(in[c]); } vector < pair <int, int>> edge; int cur = -1; void move(int m) { while (cur > m) { int c = edge[cur].s; f1.range(in[c], ou[c], -edge[cur].f); f2.range(in[c], ou[c], 1); cur--; } while (cur < m) { cur++; int c = edge[cur].s; f1.range(in[c], ou[c], edge[cur].f); f2.range(in[c], ou[c], -1); } } void bin(int l, int r, vector < vector <ll>>& save) { if (l > r || save.empty()) return; int m = (l + r) / 2; move(m); vector < vector <ll>> win, lose; for (auto x : save) { if (sum(x[0], x[1], f1) <= x[3]) { ans[x[4]] = sum(x[0], x[1], f2); win.pb(x); } else { lose.pb(x); } } if (sz(lose)) bin(l, m - 1, lose); if (sz(win)) bin(m + 1, r, win); } int X[N], S[N], T[N]; int main(){ ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0); int n, m, q; cin >> n >> m >> q; fill(ans, ans + q + 1, 2e9); f1.ass(n + 100); f2.ass(n + 100); for (int i = 1; i < n; i++) { int a, b; cin >> a >> b; ed[a].pb({b, i}); ed[b].pb({a, i}); } dfs(1, 1); for (int i = 1; i <= m; i++) { int p, c; cin >> p >> c; p = id[p]; f2.range(in[p], ou[p], 1); edge.pb({c, p}); } sort(all(edge)); vector < vector <ll>> save; for (int i = 1; i <= q; i++) { ll s, t, x, y; cin >> s >> t >> x >> y; save.pb({s, t, x, y, i}); ans[i] = sum(s, t, f2); X[i] = x; S[i] = s; T[i] = t; } bin(0, sz(edge) - 1, save); for (int i = 1; i <= q; i++) { if (X[i] < ans[i]) { cout << -1 << '\n'; } else { cout << X[i] - ans[i] << '\n'; } } return 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...