제출 #463785

#제출 시각아이디문제언어결과실행 시간메모리
463785JovanBDynamic Diameter (CEOI19_diameter)C++17
49 / 100
5061 ms141484 KiB
#include <bits/stdc++.h> using namespace std; using ll = long long; using ld = long double; const int N = 100000; const int LOG = 18; vector <pair <int, int>> graf[N+5]; int sz[N+5], A[N+5], B[N+5]; ll w[N+5]; bool erased[N+5]; void dfs_size(int v, int p){ sz[v] = 1; for(auto pr : graf[v]){ int c = pr.first; if(erased[c] || c == p) continue; dfs_size(c, v); sz[v] += sz[c]; } } int find_centroid(int v, int p, int sve){ for(auto c : graf[v]) if(!erased[c.first] && c.first != p && 2*sz[c.first] > sve) return find_centroid(c.first, v, sve); return v; } int in[LOG+1][N+5], out[LOG+1][N+5], par[LOG+1][N+5], kome[LOG+1][N+5]; ll niz[LOG+1][N+5]; int tjm[LOG+1]; struct Segment{ ll val[4*N+5]; ll lazy[4*N+5]; void propagate(int node, int l, int r){ val[node] += lazy[node]; if(l == r){ lazy[node] = 0; return; } lazy[node*2] += lazy[node]; lazy[node*2+1] += lazy[node]; lazy[node] = 0; } void init(int node, int l, int r, int lg){ if(l == r){ val[node] = niz[lg][l]; return; } int mid = (l+r)/2; init(node*2, l, mid, lg); init(node*2+1, mid+1, r, lg); val[node] = max(val[node*2], val[node*2+1]); } void upd(int node, int l, int r, int tl, int tr, ll v){ propagate(node, l, r); if(tl > r || l > tr) return; if(tl <= l && r <= tr){ lazy[node] += v; propagate(node, l, r); return; } int mid = (l+r)/2; upd(node*2, l, mid, tl, tr, v); upd(node*2+1, mid+1, r, tl, tr, v); val[node] = max(val[node*2], val[node*2+1]); } ll query(int node, int l, int r, int tl, int tr){ propagate(node, l, r); if(tl > r || l > tr) return 0; if(tl <= l && r <= tr) return val[node]; int mid = (l+r)/2; return max(query(node*2, l, mid, tl, tr), query(node*2+1, mid+1, r, tl, tr)); } } seg[LOG+1]; void dfs_depth(int v, int p, ll d, int depth, int root){ par[depth][v] = p; kome[depth][v] = root; in[depth][v] = ++tjm[depth]; niz[depth][in[depth][v]] = d; for(auto pr : graf[v]){ int c, dc; tie(c, dc) = pr; if(erased[c] || c == p) continue; dfs_depth(c, v, d + w[dc], depth, root); } out[depth][v] = tjm[depth]; } int kd[N+5]; void decompose(){ queue <pair <int, int>> q; q.push({1, 1}); while(!q.empty()){ int v, d; tie(v, d) = q.front(); q.pop(); dfs_size(v, 0); v = find_centroid(v, 0, sz[v]); kd[v] = d; for(auto c : graf[v]){ if(erased[c.first]) continue; dfs_depth(c.first, v, w[c.second], d, c.first); } erased[v] = 1; for(auto c : graf[v]) if(!erased[c.first]) q.push({c.first, d + 1}); } } multiset <ll> lengths[N+5]; multiset <ll> sol; ll calc(int v){ if(lengths[v].size() == 0) return 0; if(lengths[v].size() == 1) return *lengths[v].begin(); ll x = *lengths[v].rbegin(); ll d = x; lengths[v].erase(lengths[v].find(x)); d += *lengths[v].rbegin(); lengths[v].insert(x); return d; } ll rez[N+5]; ll dole[LOG+1][N+5]; int main(){ ios_base::sync_with_stdio(false), cin.tie(0); cout.precision(10); cout << fixed; int n, qrs; ll W; cin >> n >> qrs >> W; for(int i=1; i<n; i++){ int a, b; ll c; cin >> a >> b >> c; graf[a].push_back({b, i}); graf[b].push_back({a, i}); w[i] = c; A[i] = a; B[i] = b; } decompose(); for(int i=1; i<=LOG; i++) seg[i].init(1, 1, n, i); for(int v=1; v<=n; v++){ int lg = kd[v]; for(auto pr : graf[v]){ int c = pr.first; if(kd[c] <= lg) continue; lengths[v].insert(dole[lg][c] = seg[lg].query(1, 1, n, in[lg][c], out[lg][c])); } sol.insert(rez[v] = calc(v)); } ll res = 0; while(qrs--){ int edg; ll d; cin >> edg >> d; edg = 1 + (edg + res)%(n-1); d = (d + res)%W; int a = A[edg], b = B[edg]; for(int lg=1; lg<=LOG; lg++){ if(kd[a] < lg || kd[b] < lg) break; if(par[lg][a] == b) swap(a, b); int c = kome[lg][b]; int v = par[lg][c]; sol.erase(sol.find(rez[v])); lengths[v].erase(lengths[v].find(dole[lg][c])); seg[lg].upd(1, 1, n, in[lg][b], out[lg][b], d - w[edg]); lengths[v].insert(dole[lg][c] = seg[lg].query(1, 1, n, in[lg][c], out[lg][c])); sol.insert(rez[v] = calc(v)); } w[edg] = d; res = *sol.rbegin(); cout << res << "\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...