Submission #1185601

#TimeUsernameProblemLanguageResultExecution timeMemory
1185601epicci23Grapevine (NOI22_grapevine)C++20
100 / 100
514 ms52416 KiB
#include "bits/stdc++.h" #define int long long #define all(v) v.begin() , v.end() #define sz(a) (int)a.size() using namespace std; const int INF = 1e18; const int INF2 = 5e15; const int N = 1e5 + 5; vector<array<int,2>> Edges; // first element is Xor of edge points, second element is weight vector<int> v[N],eski; map<array<int,2>,int> mp; int n, q, depth[N], sub[N], vis[N], mark[N], ans[N], tin[N], tout[N], ti, comp; vector<int> Ac[N], Sor[N]; vector<array<int,2>> Degis[N]; vector<int> add, seg, lazy, base; void init(int _n){ seg.assign(4 * _n + 5, INF); add.assign(_n + 5, 0); lazy.assign(4 * _n + 5, 0); base.assign(_n + 5, 0); } inline void push(int rt,int l,int r){ if(lazy[rt] == 0) return; int u = lazy[rt]; lazy[rt] = 0; seg[rt] += u; if(l == r){ add[l] += u; return; } lazy[rt * 2] += u; lazy[rt * 2 + 1] += u; } void upd(int rt,int l,int r,int gl,int gr,int u){ if(l > r || gl > gr) return; push(rt, l, r); if(r < gl || l > gr) return; if(l >= gl && r <= gr){ lazy[rt] += u; push(rt, l, r); return; } int mid = (l + r) / 2; upd(rt * 2, l, mid, gl, gr, u); upd(rt * 2 + 1, mid + 1, r, gl, gr, u); seg[rt] = min(seg[rt * 2], seg[rt * 2 + 1]); } int Find(int rt,int l,int r,int ind){ push(rt, l, r); if(l == r) return base[l] + add[l]; int mid = (l + r) / 2; if(ind <= mid) return Find(rt * 2, l, mid, ind); return Find(rt * 2 + 1, mid + 1, r, ind); } void Open(int rt,int l,int r,int ind){ push(rt, l, r); if(r < ind || l > ind) return; if(l == r){ seg[rt] = add[l] + base[l]; return; } int mid = (l + r) / 2; Open(rt * 2, l, mid, ind), Open(rt * 2 + 1, mid + 1, r, ind); seg[rt] = min(seg[rt * 2], seg[rt * 2 + 1]); } void Close(int rt,int l,int r,int ind){ push(rt, l, r); if(r < ind || l > ind) return; if(l == r){ seg[rt] = INF; return; } int mid = (l + r) / 2; Close(rt * 2, l, mid, ind), Close(rt * 2 + 1, mid + 1, r, ind); seg[rt] = min(seg[rt * 2], seg[rt * 2 + 1]); } void hehe(int c,int p){ sub[c] = 1; comp++; for(int ind : v[c]){ int u = Edges[ind][0] ^ c; if(u == p || vis[u]) continue; hehe(u, c); sub[c] += sub[u]; } } int Find_Centroid(int c,int p){ for(int ind : v[c]){ int u = Edges[ind][0] ^ c; if(u == p || vis[u] || comp / 2 > sub[u]) continue; return Find_Centroid(u, c); } return c; } vector<array<int,3>> Events; void dep(int c,int p,int d){ tin[c] = ++ti; depth[c] = base[ti] = d; //cout << "suann : " << c << ' ' << d << '\n'; mark[c] = 0; for(int u : Sor[c]) Events.push_back({u, c, -1}); for(int u : Ac[c]) Events.push_back({u, c, -2}); for(int ind : v[c]){ int u = Edges[ind][0] ^ c; if(u == p || vis[u]) continue; for(auto X : Degis[ind]) Events.push_back({X[0], X[1], u}); dep(u, c, d + eski[ind]); } tout[c] = ti; } void calc(int c,int p){ ti = comp = 0; hehe(c, p); c = Find_Centroid(c, p); init(comp + 5); //cout << "root : " << c << '\n'; Events.clear(); dep(c, p, 0); sort(all(Events)); for(auto X : Events){ if(X[2] == -1){ ans[X[0]] = min(ans[X[0]], Find(1,1,comp,tin[X[1]]) + seg[1]); } else if(X[2] == -2){ if(mark[X[1]]) Close(1,1,comp,tin[X[1]]); else Open(1,1,comp,tin[X[1]]); mark[X[1]] ^= 1; } else{ //cout << 1 << ' ' << comp << ' ' << tin[X[2]] << ' ' << tout[X[2]] << ' ' << X[1] << '\n'; upd(1,1,comp,tin[X[2]],tout[X[2]],X[1]); } } vis[c] = 1; for(int ind : v[c]){ int u = Edges[ind][0] ^ c; if(vis[u] || u == p) continue; calc(u, c); } } void _(){ cin >> n >> q; for(int i=0;i+1<n;i++){ int a,b,c; cin >> a >> b >> c; v[a].push_back(sz(Edges)); v[b].push_back(sz(Edges)); eski.push_back(c); Edges.push_back({a ^ b, c}); mp[{a, b}] = mp[{b, a}] = i; } vector<int> Haha; for(int i=1;i<=q;i++){ int op; cin >> op; if(op == 1){ int node; cin >> node; Haha.push_back(i); ans[i] = INF; Sor[node].push_back(i); } else if(op == 2){ int node; cin >> node; Ac[node].push_back(i); } else{ int a, b, c; cin >> a >> b >> c; int ind = mp[{a, b}]; //cout << "noldu : " << c - Edges[ind][1] << '\n'; Degis[ind].push_back({i, c - Edges[ind][1]}); Edges[ind][1] = c; } } calc(1, -1); for(int hmhm : Haha){ if(ans[hmhm] >= INF2) cout << -1 << '\n'; else cout << ans[hmhm] << '\n'; } } int32_t main(){ cin.tie(0); ios::sync_with_stdio(0); int tc=1;//cin >> tc; while(tc--) _(); 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...