제출 #1169755

#제출 시각아이디문제언어결과실행 시간메모리
1169755daoquanglinh2007Grapevine (NOI22_grapevine)C++20
100 / 100
1277 ms242612 KiB
#include <bits/stdc++.h> using namespace std; #define ll long long #define pii pair <int, int> #define fi first #define se second #define mp make_pair #define isz(a) (int)(a).size() const int NM = 1e5; const ll inf = 1e18, LIM = 1e16; struct node{ ll d, res; }; int n, q, sz[NM+5], num[NM+5], parent_cen[NM+5], timer; bool del[NM+5]; vector <pii> adj[NM+5]; vector <int> vlist[NM+5], tin[NM+5], tout[NM+5], tour[NM+5], f[NM+5]; vector <ll> d[NM+5], lazy[NM+5]; vector <node> st[NM+5]; vector <int> tmp; map <pii, int> len; void dfs_sz(int u, int p){ sz[u] = 1; tmp.push_back(u); for (pii _ : adj[u]){ int v = _.fi; if (v == p || del[v]) continue; dfs_sz(v, u); sz[u] += sz[v]; } } int dfs_fc(int rt, int u, int p){ for (pii _ : adj[u]){ int v = _.fi; if (v == p || del[v]) continue; if (sz[v] > sz[rt]/2) return dfs_fc(rt, v, u); } return u; } void dfs_dp(int rt, int u, int p, int pos_u){ tin[rt][pos_u] = timer++; tour[rt][timer-1] = pos_u; for (pii _ : adj[u]){ int v = _.fi, w = _.se; if (v == p || del[v]) continue; int pos_v = lower_bound(vlist[rt].begin(), vlist[rt].end(), v)-vlist[rt].begin(); d[rt][pos_v] = d[rt][pos_u]+w; if (u == rt) f[rt][pos_v] = pos_v; else f[rt][pos_v] = f[rt][pos_u]; dfs_dp(rt, v, u, pos_v); } tout[rt][pos_u] = timer-1; } void build(int rt, int id, int l, int r){ st[rt][id].res = +inf; if (l == r){ st[rt][id].d = d[rt][tour[rt][l]]; return; } int mid = (l+r)/2; build(rt, 2*id, l, mid); build(rt, 2*id+1, mid+1, r); } void decompose(int u, int p){ tmp.clear(); dfs_sz(u, -1); sort(tmp.begin(), tmp.end()); u = dfs_fc(u, u, -1); parent_cen[u] = p; del[u] = 1; vlist[u] = tmp; num[u] = isz(vlist[u]); tin[u].resize(num[u]); tout[u].resize(num[u]); tour[u].resize(num[u]); f[u].resize(num[u]); d[u].resize(num[u]); timer = 0; dfs_dp(u, u, -1, lower_bound(vlist[u].begin(), vlist[u].end(), u)-vlist[u].begin()); st[u].resize(4*num[u]+1); build(u, 1, 0, num[u]-1); lazy[u].assign(4*num[u]+1, 0); for (pii _ : adj[u]){ int v = _.fi; if (del[v]) continue; decompose(v, u); } } void down(int rt, int id, int l, int r){ int mid = (l+r)/2; if (l == mid) st[rt][2*id].d += lazy[rt][id]; if (mid+1 == r) st[rt][2*id+1].d += lazy[rt][id]; st[rt][2*id].res += lazy[rt][id]; st[rt][2*id+1].res += lazy[rt][id]; lazy[rt][2*id] += lazy[rt][id]; lazy[rt][2*id+1] += lazy[rt][id]; lazy[rt][id] = 0; } void p_update(int rt, int id, int l, int r, int i){ if (i < l || i > r) return; if (l == r){ if (st[rt][id].res > LIM) st[rt][id].res = st[rt][id].d; else st[rt][id].res = +inf; return; } down(rt, id, l, r); int mid = (l+r)/2; p_update(rt, 2*id, l, mid, i); p_update(rt, 2*id+1, mid+1, r, i); st[rt][id].res = min(st[rt][2*id].res, st[rt][2*id+1].res); } void add(int rt, int id, int l, int r, int u, int v, int val){ if (u > v || v < l || u > r) return; if (l >= u && r <= v){ if (l == r) st[rt][id].d += val; st[rt][id].res += val; lazy[rt][id] += val; return; } down(rt, id, l, r); int mid = (l+r)/2; add(rt, 2*id, l, mid, u, v, val); add(rt, 2*id+1, mid+1, r, u, v, val); st[rt][id].res = min(st[rt][2*id].res, st[rt][2*id+1].res); } ll get(int rt, int id, int l, int r, int u, int v){ if (u > v || v < l || u > r) return +inf; if (l >= u && r <= v) return st[rt][id].res; down(rt, id, l, r); int mid = (l+r)/2; return min(get(rt, 2*id, l, mid, u, v), get(rt, 2*id+1, mid+1, r, u, v)); } ll get_d(int rt, int id, int l, int r, int i){ if (l == r) return st[rt][id].d; down(rt, id, l, r); int mid = (l+r)/2; if (i <= mid) return get_d(rt, 2*id, l, mid, i); return get_d(rt, 2*id+1, mid+1, r, i); } ll query(int rt, int u){ if (rt == u) return st[rt][1].res; int pos_u = lower_bound(vlist[rt].begin(), vlist[rt].end(), u)-vlist[rt].begin(); return min(get(rt, 1, 0, num[rt]-1, 0, tin[rt][f[rt][pos_u]]-1), get(rt, 1, 0, num[rt]-1, tout[rt][f[rt][pos_u]]+1, num[rt]-1)) +get_d(rt, 1, 0, num[rt]-1, tin[rt][pos_u]); } void soak(int rt, int u){ int pos_u = lower_bound(vlist[rt].begin(), vlist[rt].end(), u)-vlist[rt].begin(); p_update(rt, 1, 0, num[rt]-1, tin[rt][pos_u]); } void add(int rt, int u, int v, int val){ int pos_u = lower_bound(vlist[rt].begin(), vlist[rt].end(), u)-vlist[rt].begin(); int pos_v = lower_bound(vlist[rt].begin(), vlist[rt].end(), v)-vlist[rt].begin(); if (tin[rt][pos_u] < tin[rt][pos_v]){ add(rt, 1, 0, num[rt]-1, tin[rt][pos_v], tout[rt][pos_v], val); } else{ add(rt, 1, 0, num[rt]-1, tin[rt][pos_u], tout[rt][pos_u], val); } } signed main(){ ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin >> n >> q; for (int i = 1; i < n; i++){ int u, v, w; cin >> u >> v >> w; len[mp(u, v)] = len[mp(v, u)] = w; adj[u].push_back(mp(v, w)); adj[v].push_back(mp(u, w)); } decompose(1, -1); while (q--){ int type; cin >> type; if (type == 1){ int u; cin >> u; ll ans = +inf; for (int rt = u; rt != -1; rt = parent_cen[rt]){ ans = min(ans, query(rt, u)); } if (ans > LIM) cout << "-1\n"; else cout << ans << '\n'; } else if (type == 2){ int u; cin >> u; for (int rt = u; rt != -1; rt = parent_cen[rt]) soak(rt, u); } else{ int u, v, w; cin >> u >> v >> w; int pre = len[mp(u, v)]; if (num[u] < num[v]) swap(u, v); for (int rt = u; rt != -1; rt = parent_cen[rt]) add(rt, u, v, w-pre); len[mp(u, v)] = len[mp(v, u)] = w; } } 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...