Submission #1278734

#TimeUsernameProblemLanguageResultExecution timeMemory
1278734Mike_VuTwo Currencies (JOI23_currencies)C++17
0 / 100
2 ms2884 KiB
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef unsigned long long ull; typedef double dou; #define pii pair<int, int> #define fi first #define se second #define pb push_back #define BITJ(x, j) (((x)>>(j))&1) #define MASK(j) (1LL<<(j)) #define ALL(v) v.begin(), v.end() template<typename T> bool maximize(T &x, const T &y) { if (x < y) {x = y; return 1;} return 0; } template<typename T> bool minimize(T &x, const T &y) { if (x > y) {x = y; return 1;} return 0; } struct BIT{ int n; vector<ll> bit; void init(int _n) { n = _n; bit.assign(n+1, 0); } void upd(int k, ll x) { while (k <= n) { bit[k] += x; k += k & (-k); } } void update(int l, int r, ll x) { upd(l, x); upd(r+1, -x); } ll getsum(int k){ ll res = 0; while (k > 0) { res += bit[k]; k -= k & (-k); } return res; } }; struct query{ int u, v, lca; ll gold, silver, ans = -1; query(int _u, int _v, int _lca, ll _gold, ll _silver) { u = _u; v = _v; lca = _lca; gold = _gold; silver = _silver; } }; const int maxn = 1e5+5, lg = 17; int n, m, q; vector<pii> edges; vector<int> adj[maxn]; int tin[maxn], tout[maxn], timer = 0, h[maxn], par[maxn][lg]; BIT bit, bitcnt; vector<pair<ll,int>> updates; //val, node, sort by val vector<query> qu; void dfsprep(int u, int p) { for (int j = 1; j < lg; j++) { if (MASK(j) >= h[u]) continue; par[u][j] = par[par[u][j-1]][j-1]; } tin[u] = ++timer; for (int v : adj[u]) { if (v == p) continue; par[v][0] = u; h[v] = h[u] + 1; dfsprep(v, u); } tout[u] = timer; } bool inside(int u, int v){ return (tin[u] <= tin[v] && tout[v] <= tout[u]); } int findlca(int u, int v) { if (inside(u, v)) return v; if (inside(v, u)) return u; for (int j = lg-1; j >= 0; j--){ while (MASK(j) < h[u] && !inside(par[u][j], v)) { u = par[u][j]; } } return par[u][0]; } void prlbs() { vector<int> bleft, bright, bmid, id; //update val, update 1 bleft.assign(q, 0); bright.assign(q, m); bmid.assign(q, m/2); while (true) { bool can = 0; id.clear(); for (int i = 0; i < q; i++) { if (bleft[i] <= bright[i]) { can = 1; bmid[i] = (bleft[i]+bright[i])>>1; id.pb(i); } } if (!can) break; sort(ALL(id), [&](int a, int b){return bmid[a] < bmid[b];}); int j = 0; bit.init(n); bitcnt.init(n); for (int i = 0; i < m; i++) { int u = updates[i].se; bitcnt.update(tin[u], tout[u], 1); } for (int i : id){ while (j < bmid[i]) { int u = updates[j].se; bit.update(tin[u], tout[u], updates[j].fi); bitcnt.update(tin[u], tout[u], -1); ++j; } // cout << "mid " << bmid[i] << "\n"; ll sum = bit.getsum(tin[qu[i].u])+bit.getsum(tin[qu[i].v]); sum -= bit.getsum(tin[qu[i].lca])*2; // cout << sum << "\n"; if (sum > qu[i].silver) { //case too much bright[i] = bmid[i]-1; continue; } int cnt = bitcnt.getsum(tin[qu[i].u])+bitcnt.getsum(tin[qu[i].v]); sum -= bitcnt.getsum(tin[qu[i].lca])*2; // cout << cnt << "\n"; if (cnt > qu[i].gold){ //case too low bleft[i] = bmid[i]+1; continue; } //case ok, try to find if there is any optimal solution maximize(qu[i].ans, qu[i].gold-cnt); bleft[i] = bmid[i]+1; } } } int main() { ios_base::sync_with_stdio(0); cin.tie(0); // #define name "task" // if (fopen(name".inp", "r")) { // freopen(name".inp", "r", stdin); // freopen(name".out", "w", stdout); // } //input cin >> n >> m >> q; for (int i = 1; i < n; i++) { int u, v; cin >> u >> v; edges.pb({u, v}); adj[u].pb(v); adj[v].pb(u); } //dfs tin tout h[1] = 1; dfsprep(1, -1); //take updates, rephrase, sort for (int i= 1; i <= m; i++) { int p; ll x; cin >> p >> x; --p; int u = tin[edges[p].fi] > tin[edges[p].se] ? edges[p].fi : edges[p].se; // cout << p << ' ' << u << "\n"; updates.pb(make_pair(x, u)); } sort(ALL(updates)); //take queries for (int i= 1; i <= q; i++) { int u, v; ll gold, silver; cin >> u >> v >> gold >> silver; // cout << u << ' ' << v << ' ' << findlca(u, v) << "\n"; qu.pb(query(u, v, findlca(u, v), gold, silver)); } //parallel binsearch prlbs(); //output for (int i = 0; i < q; i++) { cout << qu[i].ans << "\n"; } } /* 5 4 1 1 2 1 3 2 4 2 5 2 9 2 4 3 5 4 7 3 4 2 11 5 4 3 1 2 1 3 2 4 2 5 2 9 2 4 3 5 4 7 3 4 2 11 5 3 4 5 2 3 1 1 */
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...