Submission #1302675

#TimeUsernameProblemLanguageResultExecution timeMemory
1302675AMel0nDynamic Diameter (CEOI19_diameter)C++20
100 / 100
2815 ms153304 KiB
#include <bits/stdc++.h> using namespace std; typedef long long ll; #define FOR(i,N) for(ll i = 0; i < N; i++) #define all(x) (x).begin(), (x).end() #define F first #define S second constexpr ll INF = 1e18; constexpr int MAXLOG = 18; constexpr int MAXN = 1e5 + 5; int N, Q; ll W; vector<pair<int,int>> adj[MAXN]; ll wt[MAXN]; pair<int,int> edge[MAXN]; int in[MAXLOG][MAXN], out[MAXLOG][MAXN], dep[MAXLOG][MAXN], anc[MAXLOG][MAXN], child[MAXLOG][MAXN]; int cnt[MAXLOG]; multiset<ll> cenbest[MAXN]; ll chbest[MAXLOG][MAXN]; priority_queue<pair<ll,int>> best; int sz[MAXN]; bool del[MAXN]; ll st[MAXLOG][MAXN*4], lazy[MAXLOG][MAXN*4]; inline void pushdown(int t, int tl, int tr, int i) { if (lazy[t][i]) { st[t][i] += lazy[t][i]; if (tl != tr) { lazy[t][i * 2] += lazy[t][i]; lazy[t][i * 2 + 1] += lazy[t][i]; } lazy[t][i] = 0; } } inline void update(int t, ll v, int l, int r, int tl = 0, int tr = N-1, int i = 1) { pushdown(t, tl, tr, i); if (l > r) return ; if (tl == l && tr == r) { st[t][i] += v; if (tl != tr) { lazy[t][i * 2] += v; lazy[t][i * 2 + 1] += v; } return ; } int tm = (tl + tr) / 2; update(t, v, l, min(r, tm), tl, tm, i * 2); update(t, v, max(l, tm + 1), r, tm + 1, tr, i * 2 + 1); st[t][i] = max(st[t][i * 2], st[t][i * 2 + 1]); } inline ll query(int t, int l, int r, int tl = 0, int tr = N-1, int i = 1) { pushdown(t, tl, tr, i); if (l > r) return 0; if (tl == l && tr == r) return st[t][i]; int tm = (tl + tr) / 2; return max(query(t, l, min(r, tm), tl, tm, i * 2), query(t, max(l, tm + 1), r, tm + 1, tr, i * 2 + 1)); } inline int dfsSZ(int v, int p) { sz[v] = 1; for(const auto &u: adj[v]) { if (del[u.F] || u.F == p) continue; sz[v] += dfsSZ(u.F, v); } return sz[v]; } inline int dfsCEN(int v, int p, int treeSZ) { for(const auto &u: adj[v]) { if (del[u.F] || u.F == p || sz[u.F] * 2 <= treeSZ) continue; return dfsCEN(u.F, v, treeSZ); } return v; } inline void dfs(int t, int v, int p, ll d, int cen, int ch) { dep[t][v] = dep[t][p] + 1; child[t][v] = ch; anc[t][v] = cen; in[t][v] = cnt[t]++; update(t, d, in[t][v], in[t][v]); for(const auto &u: adj[v]) { if (u.F == p || del[u.F]) continue; dfs(t, u.F, v, d + wt[u.S], cen, ch); } out[t][v] = cnt[t]; } inline ll calcbest(int cen) { if (cenbest[cen].size() == 1) { return *cenbest[cen].begin(); } auto it = cenbest[cen].end(); ll a = *--it; ll b = *--it; return a + b; } inline void build(int v = 0, int t = 0) { int treeSZ = dfsSZ(v, v); if (treeSZ <= 1) return ; int cen = dfsCEN(v, v, treeSZ); for(const auto &u: adj[cen]) { if (del[u.F]) continue; dfs(t, u.F, cen, wt[u.S], cen, u.F); ll q = query(t, in[t][u.F], out[t][u.F]-1); cenbest[cen].insert(q); chbest[t][u.F] = q; } best.emplace(calcbest(cen), cen); del[cen] = true; for(const auto &u: adj[cen]) { if (del[u.F]) continue; build(u.F, t + 1); } } signed main() { cin.tie(0); ios::sync_with_stdio(false); cin >> N >> Q >> W; FOR(i, MAXLOG) FOR(j, MAXN) anc[i][j] = -1; FOR(i, N-1) { int a, b; cin >> a >> b >> wt[i]; a--; b--; edge[i] = {a, b}; adj[a].emplace_back(b, i); adj[b].emplace_back(a, i); } build(); ll last = 0; FOR(i, Q) { int d; ll e; cin >> d >> e; d = (d + last) % (N-1); e = (e + last) % W; ll upd = e - wt[d]; wt[d] = e; auto [u, v] = edge[d]; FOR(t, MAXLOG) { if (anc[t][u] == anc[t][v] && anc[t][u] != -1 && anc[t][v] != -1 || (anc[t][v] == u || anc[t][u] == v)) { if (dep[t][v] < dep[t][u]) swap(u, v); update(t, upd, in[t][v], out[t][v]-1); int ch = child[t][v]; int cen = anc[t][v]; cenbest[cen].erase(cenbest[cen].find(chbest[t][ch])); chbest[t][ch] = query(t, in[t][ch], out[t][ch]-1); cenbest[cen].insert(chbest[t][ch]); best.emplace(calcbest(cen), cen); } } while (true) { if (best.top().F != calcbest(best.top().S)) best.pop(); else break; } last = best.top().F; cout << last << '\n'; } }
#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...