제출 #907009

#제출 시각아이디문제언어결과실행 시간메모리
907009CDuongTwo Currencies (JOI23_currencies)C++17
100 / 100
643 ms94528 KiB
/* #pragma GCC optimize("Ofast,unroll-loops") #pragma GCC target("avx2,fma,bmi,bmi2,sse4.2,popcnt,lzcnt") */ #include <bits/stdc++.h> #define taskname "" #define all(x) x.begin(), x.end() #define rall(x) x.rbegin(), x.rend() #define int long long #define i64 long long #define pb push_back #define ff first #define ss second #define isz(x) (int)x.size() using namespace std; const int mxN = 1e5 + 5; const int mod = 1e9 + 7; const int LOG = 20; const i64 oo = 1e18; void adds(pair<i64, int> &val, pair<i64, int> nval) { val.ff += nval.ff; val.ss += nval.ss; } struct FenwickTree { int n; vector<pair<i64, int>> data; FenwickTree() {}; FenwickTree(int n) : n(n), data(n + 10) {} void update(int idx, pair<i64, int> val) { while (idx <= n) { adds(data[idx], val); idx += idx & -idx; } } pair<i64, int> get(int idx) { pair<i64, int> res = {0, 0}; while (idx) { adds(res, data[idx]); idx -= idx & -idx; } return res; } } fenw; struct Checkpoint { int p, c; Checkpoint(int p, int c) : p(p), c(c) {} bool operator < (const Checkpoint &cp) const { return c < cp.c; } }; struct Query { int s, t, x, y; Query(int s, int t, int x, int y) : s(s), t(t), x(x), y(y) {} }; int n, m, q, ans[mxN]; vector<Query> qq; vector<Checkpoint> cp; pair<int, int> edges[mxN]; vector<pair<int, int>> G[mxN]; int tin[mxN], tout[mxN], ap[mxN], par[mxN], dep[mxN], cnt_edges[mxN], h[mxN], tdfs, ecnt; pair<int, int> euler[LOG][2 * mxN]; int ptr_pbs = -1; void dfs(int v, int p) { tin[v] = ++tdfs; dep[v] = dep[p] + 1; par[v] = p; euler[0][++ecnt] = {dep[v], v}; ap[v] = ecnt; for (auto [u, eidx] : G[v]) if (u != p) { h[u] = h[v] + cnt_edges[eidx]; dfs(u, v); euler[0][++ecnt] = {dep[v], v}; } tout[v] = tdfs; } void build_euler() { for (int i = 1, p = 1; (p << 1) <= ecnt; ++i, p <<= 1) { for (int j = 1; j + (p << 1) - 1 <= ecnt; ++j) { euler[i][j] = min(euler[i - 1][j], euler[i - 1][j + p]); } } } int LCA(int u, int v) { int l = ap[u], r = ap[v]; if (l > r) swap(l, r); int len = r - l + 1, lg_len = 31 - __builtin_clz(len); return min(euler[lg_len][l], euler[lg_len][r - (1 << lg_len) + 1]).ss; } void add(int cpidx) { auto [p, c] = cp[cpidx]; auto [u, v] = edges[p]; if (dep[u] < dep[v]) swap(u, v); fenw.update(tin[u], {c, 1}); fenw.update(tout[u] + 1, {-c, -1}); } void del(int cpidx) { auto [p, c] = cp[cpidx]; auto [u, v] = edges[p]; if (dep[u] < dep[v]) swap(u, v); fenw.update(tin[u], {-c, -1}); fenw.update(tout[u] + 1, {c, 1}); } void pbs(int l, int r, vector<int> &qq_idx) { if (l > r or qq_idx.empty()) return; int mid = (l + r) >> 1; while (ptr_pbs < mid) add(++ptr_pbs); while (ptr_pbs > mid) del(ptr_pbs--); vector<int> qql, qqr; for (int idx : qq_idx) { auto [s, t, x, y] = qq[idx]; int lca = LCA(s, t); pair<i64, int> total_silver = {0, 0}; adds(total_silver, fenw.get(tin[s])); adds(total_silver, fenw.get(tin[t])); auto cur = fenw.get(tin[lca]); cur.ff *= -2, cur.ss *= -2; adds(total_silver, cur); if (total_silver.ff <= x) { ans[idx] = max(ans[idx], y - (h[s] + h[t] - 2 * h[lca] - total_silver.ss)); qqr.emplace_back(idx); } else { qql.emplace_back(idx); } } pbs(l, mid - 1, qql); pbs(mid + 1, r, qqr); } void solve() { cin >> n >> m >> q; fenw = FenwickTree(n); for (int i = 1; i < n; ++i) { int u, v; cin >> u >> v; G[u].emplace_back(v, i); G[v].emplace_back(u, i); edges[i] = {u, v}; } for (int i = 1; i <= m; ++i) { int p, c; cin >> p >> c; cp.emplace_back(p, c); cnt_edges[p]++; } sort(all(cp)); for (int i = 1; i <= q; ++i) { int s, t, x, y; cin >> s >> t >> y >> x; qq.emplace_back(s, t, x, y); ans[i - 1] = -1; } dfs(1, 0); build_euler(); vector<int> qq_idx(q); iota(all(qq_idx), 0); pbs(-1, m - 1, qq_idx); for (int i = 0; i < q; ++i) cout << ans[i] << "\n"; } signed main() { #ifndef CDuongg if(fopen(taskname".inp", "r")) assert(freopen(taskname".inp", "r", stdin)), assert(freopen(taskname".out", "w", stdout)); #else freopen("bai3.inp", "r", stdin); freopen("bai3.out", "w", stdout); auto start = chrono::high_resolution_clock::now(); #endif ios_base::sync_with_stdio(false); cin.tie(nullptr); int t = 1; //cin >> t; while(t--) solve(); #ifdef CDuongg auto end = chrono::high_resolution_clock::now(); // cout << "\n"; for(int i = 1; i <= 100; ++i) cout << '='; // cout << "\nExecution time: " << chrono::duration_cast<chrono::milliseconds> (end - start).count() << "[ms]" << endl; // cout << "Check array size pls sir" << endl; #endif }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...