제출 #1181694

#제출 시각아이디문제언어결과실행 시간메모리
1181694GrayTwo Currencies (JOI23_currencies)C++20
100 / 100
4681 ms112140 KiB
#include <algorithm> #include <bits/stdc++.h> using namespace std; #define ll long long #define ull unsigned long long #define ld long double #define ff first #define ss second #define ln "\n" #define mp make_pair #define pb push_back #define INF (ll)2e18 #define MOD 998244353 struct SegTree{ vector<vector<ll>> t; vector<vector<ll>> tpref; ll sz, rsz; void init(ll N){ sz=N*4; rsz=N; tpref.resize(sz); t.resize(sz); } void build(ll tl, ll tr, ll v, vector<vector<ll>> &a){ if (tl==tr){ t[v] = a[tl]; tpref[v]=a[tl]; for (ll i=1; i<(ll)tpref[v].size(); i++) tpref[v][i]+=tpref[v][i-1]; }else{ ll tm = (tl+tr)/2; build(tl, tm, v*2, a); build(tm+1, tr, v*2+1, a); merge(t[v*2].begin(), t[v*2].end(), t[v*2+1].begin(), t[v*2+1].end(), back_inserter(t[v])); tpref[v].resize(t[v].size()); for (ll i=0; i<(ll)t[v].size(); i++){ tpref[v][i]=(i?tpref[v][i-1]:0ll)+t[v][i]; } } } pair<ll, ll> query(ll tl, ll tr, ll v, ll l, ll r, ll x){ if (tl==l and tr==r){ ll ind = upper_bound(t[v].begin(), t[v].end(), x)-t[v].begin()-1; pair<ll, ll> ret = {0, 0}; if (ind>=0){ ret=mp(ind+1ll, tpref[v][ind]); } return ret; }else if (l>r) return {0, 0}; else{ ll tm = (tl+tr)/2; pair<ll, ll> resl = query(tl, tm, v*2, l, min(r, tm), x); pair<ll, ll> resr = query(tm+1, tr, v*2+1, max(l, tm+1), r, x); return {resl.ff+resr.ff, resl.ss+resr.ss}; } } void build(vector<vector<ll>> &a){ build(0, rsz-1, 1, a); } pair<ll, ll> query(ll l, ll r, ll x){ // cout << l << " - " << r << " - " << x << " -> "; if (l>r) swap(l, r); pair<ll, ll> ret=query(0, rsz-1, 1, l, r, x); // cout << ret.ff << " " << ret.ss << ln; return ret; } }; struct edge{ ll u, v; vector<ll> control; }; struct HLD{ ll n; vector<edge> e; vector<vector<ll>> A; vector<ll> sz, level; vector<ll> eid, nxt; vector<vector<ll>> euler, bin /*just in case*/; SegTree ds; void dfs1(ll u, ll p, ll clev){ bin[u][0]=p; level[u]=clev; sz[u]=1; ll mxsz=0; for (ll i=1; i<20; i++) bin[u][i]=bin[bin[u][i-1]][i-1]; for (auto &i:A[u]){ ll v = e[i].u^e[i].v^u; if (v==p) continue; dfs1(v, u, clev+1); sz[u]+=sz[v]; if (mxsz<sz[v]) swap(i, A[u][0]), mxsz=sz[v]; } } void dfs2(ll u, ll p){ bool first=1; for (auto i:A[u]){ ll v = e[i].u^e[i].v^u; if (v==p) continue; eid[v]=euler.size(); euler.push_back(e[i].control); if (first) nxt[v]=nxt[u]; else nxt[v]=v; dfs2(v, u); first=0; } } HLD(ll N, vector<edge> &_e){ n=N; e=_e; A.resize(n+1); sz.resize(n+1); level.resize(n+1); nxt.resize(n+1); bin.resize(n+1, vector<ll>(20)); eid.resize(n+1); for (ll i=0; i<n-1; i++){ A[e[i].u].push_back(i); A[e[i].v].push_back(i); } nxt[1]=1; euler.push_back(vector<ll>()); dfs1(1, 1, 1); dfs2(1, 1); ds.init(N); ds.build(euler); // for (ll i=1; i<=n; i++) cout << level[i] << " "; // cout<<endl; } pair<ll, ll> queryLOW(ll u, ll v, ll c){ // cout << "ENT" << u << " - " << v << " - " << c << endl; if (u==v) return {0, 0}; pair<ll, ll> res = {0, 0}; while (nxt[u]!=nxt[v]){ // cout << u << " - " << v << " <-> "; if (level[nxt[u]]<level[nxt[v]]) swap(u, v); pair<ll, ll> ret=ds.query(eid[u], eid[nxt[u]], c); res.ff+=ret.ff; res.ss+=ret.ss; u=bin[nxt[u]][0]; } // cout << u << " - " << v << endl; // cout << "CAME" << endl; if (u!=v){ if (level[u]<level[v]) swap(u, v); ll jump = level[u]-level[v]-1; ll tu = u; for (ll i=0; i<20; i++){ if (jump&(1ull<<i)){ tu=bin[tu][i]; } } pair<ll, ll> ret=ds.query(eid[u], eid[tu], c); res.ff+=ret.ff; res.ss+=ret.ss; } // cout << "DONE -> " << res.ff << " - " << res.ss << endl; return res; } ll query(ll u, ll v, ll s, ll g){ ll l=0, r=s+2; while (l+1<r){ ll mid = (l+r)/2; if (queryLOW(u, v, mid).ss<=s) l=mid; else r=mid; } pair<ll, ll> data = queryLOW(u, v, l); ll total = queryLOW(u, v, 2e9).ff; total-=data.ff; s-=data.ss; total-=s/(l+1); return max(-1ll, g-total); } }; void solve(){ ll n, m, q; cin >> n >> m >> q; vector<edge> e(n-1); for (ll i=0; i<n-1; i++){ cin >> e[i].u >> e[i].v; } for (ll i=0; i<m; i++){ ll id, x; cin >> id >> x; e[id-1].control.push_back(x); } for (ll i=0; i<n-1; i++){ sort(e[i].control.begin(), e[i].control.end()); } HLD tr(n, e); // return; while (q--){ ll u, v, g, s; cin >> u >> v >> g >> s; cout << tr.query(u, v, s, g) << ln; } } int main(){ ios_base::sync_with_stdio(false); cin.tie(nullptr); #ifdef LOCAL auto start = chrono::high_resolution_clock::now(); #endif ll t=1; // cin >> t; while (t--) solve(); #ifdef LOCAL auto duration = chrono::duration_cast<chrono::microseconds>(chrono::high_resolution_clock::now() - start); cout << setprecision(0) << fixed << "time: " << (double)duration.count()/1000.0 << " milliseconds" << 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...