Submission #1308473

#TimeUsernameProblemLanguageResultExecution timeMemory
1308473Hamed_GhaffariDesignated Cities (JOI19_designated_cities)C++20
100 / 100
551 ms54324 KiB
#include <bits/stdc++.h> using namespace std; #pragma GCC optimize("O3,unroll-loops") #pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt") using ll = long long; using pll = pair<ll, int>; #define X first #define Y second #define mins(a, b) (a = min(a,b)) #define SZ(x) int(x.size()) #define lc id<<1 #define rc lc|1 #define mid ((l+r)>>1) const int MXN = 2e5+5; int n, W[MXN<<1], xr[MXN]; vector<int> g[MXN]; bool dead[MXN], mark[MXN]; int sz[MXN]; int dfs_sz(int v, int p) { mark[v] = 0; sz[v] = 1; for(int i : g[v]) { int u = v^xr[i>>1]; if(!dead[u] && u!=p) sz[v] += dfs_sz(u, v); } return sz[v]; } int centroid(int v, int N, int p) { for(int i : g[v]) { int u = v^xr[i>>1]; if(!dead[u] && u!=p && 2*sz[u]>N) return centroid(u, N, v); } return v; } int stt[MXN], fnt[MXN], timer, ver[MXN], cmp[MXN], par[MXN]; ll sum[MXN]; void dfs_stt(int v, int p) { ver[stt[v] = timer++] = v; for(int i : g[v]) { int u = v^xr[i>>1]; if(!dead[u] && u!=p) par[u] = i, dfs_stt(u, v); } fnt[v] = timer; } pll operator+(pll x, ll y) { return pll(x.X+y, x.Y);} namespace seg { pll seg[MXN<<2]; ll lz[MXN<<2]; void build(int l=0, int r=n, int id=1) { seg[id] = pll(0, r-1); lz[id] = 0; if(r-l == 1) return; build(l, mid, lc); build(mid, r, rc); } void upd(int s, int e, ll x, int l=0, int r=n, int id=1) { if(s>=r || l>=e) return; if(s<=l && r<=e) { seg[id].X += x; lz[id] += x; return; } upd(s, e, x, l, mid, lc); upd(s, e, x, mid, r, rc); seg[id] = max(seg[lc], seg[rc]) + lz[id]; } pll get(int s, int e, int l=0, int r=n, int id=1) { if(s>=r || l>=e) return pll(-1e18, 0); if(s<=l && r<=e) return seg[id]; return max(get(s, e, l, mid, lc), get(s, e, mid, r, rc)) + lz[id]; } } void dfs_cmp(int v, int c, int p) { cmp[v] = c; sum[v] = 0; for(int i : g[v]) { int u = v^xr[i>>1]; if(!dead[u] && u!=p) { dfs_cmp(u, c, v); sum[v] += sum[u] + W[i]; seg::upd(stt[u], fnt[u], W[i]); } } } ll ans[MXN]; void solve(int v) { mark[v] = 1; timer = 0; dfs_stt(v, 0); seg::build(); ll tot_sum = 0; for(int i : g[v]) { int u = v^xr[i>>1]; if(!dead[u]) { dfs_cmp(u, u, v); sum[u] += W[i]; tot_sum += sum[u]; seg::upd(stt[u], fnt[u], W[i]); } } auto del = [&](int v) -> void { while(!mark[v]) { seg::upd(stt[v], fnt[v], -W[par[v]]); mark[v] = 1; v ^= xr[par[v]>>1]; } }; ll cur = tot_sum; for(int i=2; i<=n; i++) { if(seg::seg[1].X) { cur -= seg::seg[1].X; del(ver[seg::seg[1].Y]); } ans[i] = cur; } } int V; ll tot; void DFS(int v, int p) { stt[v] = timer++; for(int i : g[v]) { int u = v^xr[i>>1]; if(u==p) continue; DFS(u, v); tot += W[i]; seg::upd(stt[u], fnt[u], W[i]); } fnt[v] = timer; } void reroot(int v, int p) { mins(ans[1], tot); if(ans[2]>tot-seg::seg[1].X) { ans[2] = tot-seg::seg[1].X; V = v; } for(int i : g[v]) { int u = v^xr[i>>1]; if(u==p) continue; seg::upd(stt[u], fnt[u], -W[i]-W[i^1]); seg::upd(0, n, W[i^1]); tot += W[i^1]-W[i]; reroot(u, v); tot += W[i]-W[i^1]; seg::upd(stt[u], fnt[u], W[i]+W[i^1]); seg::upd(0, n, -W[i^1]); } } int32_t main() { cin.tie(0); cout.tie(0); ios_base::sync_with_stdio(0); cin >> n; for(int i=0,a,b,c,d; i<n-1; i++) { cin >> a >> b >> c >> d; g[a].push_back(i<<1); W[i<<1] = c; g[b].push_back(i<<1|1); W[i<<1|1] = d; xr[i] = a^b; } seg::build(); ans[1] = 1e18, ans[2] = 1e18; DFS(1, 0); reroot(1, 0); if(n>=3) solve(V); int q; cin >> q; while(q--) { int e; cin >> e; cout << ans[e] << '\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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...