Submission #1147853

#TimeUsernameProblemLanguageResultExecution timeMemory
1147853Tam_theguideDynamic Diameter (CEOI19_diameter)C++20
100 / 100
1643 ms32204 KiB
#include <bits/stdc++.h> using namespace std; using ll = long long; const int MAXN = 1e5 + 5; const int LG = 20; const ll INF = 2e18; int n, q, sz[MAXN], head[MAXN], pa[MAXN], in[MAXN], out[MAXN], trace[MAXN]; ll limW; vector<int> adj[MAXN], dfs_order; struct Edge { int u, v; ll w; Edge() {} Edge(int u, int v, ll w) : u(u), v(v), w(w) {} } edges[MAXN]; struct Segment_Tree { ll *seg, *lazy; Segment_Tree(int n) : seg(new ll[4 * n]), lazy(new ll[4 * n]) { memset(seg, 0, sizeof(ll) * 4 * n); memset(lazy, 0, sizeof(ll) * 4 * n); } void push(int root, ll val) { seg[root] += val; lazy[root] += val; } void update(int root, int tl, int tr, int l, int r, ll val) { if (tl > r || tr < l) return; if (tl >= l && tr <= r) { push(root, val); return; } int tm = (tl + tr) / 2; push(2 * root, lazy[root]); push(2 * root + 1, lazy[root]); lazy[root] = 0; update(2 * root, tl, tm, l, r, val); update(2 * root + 1, tm + 1, tr, l, r, val); seg[root] = max(seg[2 * root], seg[2 * root + 1]); } ll get(int root, int tl, int tr, int l, int r) { if (tl > r || tr < l || l > r) return -INF; if (tl >= l && tr <= r) return seg[root]; int tm = (tl + tr) / 2; push(2 * root, lazy[root]); push(2 * root + 1, lazy[root]); lazy[root] = 0; return max(get(2 * root, tl, tm, l, r), get(2 * root + 1, tm + 1, tr, l, r)); } int get_maxid(int root, int tl, int tr) { if (tl == tr) return trace[tl]; int tm = (tl + tr) / 2; push(2 * root, lazy[root]); push(2 * root + 1, lazy[root]); lazy[root] = 0; if (seg[2 * root] > seg[2 * root + 1]) return get_maxid(2 * root, tl, tm); else return get_maxid(2 * root + 1, tm + 1, tr); } } Find_u(MAXN), Find_v(MAXN); void dfs_sz(int p, int u) { pa[u] = p; sz[u] = 1; for (auto& id : adj[u]) { int v = edges[id].u + edges[id].v - u; if (v == p) { id = p; continue; } dfs_order.push_back(id); dfs_sz(u, v); sz[u] += sz[v]; id = v; if (sz[v] > sz[adj[u][0]]) swap(id, adj[u][0]); } for (int i = 0; i < adj[u].size(); i++) { if (adj[u][i] == p) { adj[u].erase(adj[u].begin() + i); return; } } } void dfs_head(int u) { in[u] = ++in[0]; trace[in[u]] = u; if (u == 1) head[u] = u; for (int i = 0; i < adj[u].size(); i++) { if (i == 0) head[adj[u][i]] = head[u]; else head[adj[u][i]] = adj[u][i]; dfs_head(adj[u][i]); } out[u] = in[0]; } void update(int u, ll diff) { Find_u.update(1, 1, n, in[u], out[u], diff); Find_v.update(1, 1, n, in[u], out[u], -diff); while (u != 0) { u = head[u]; int p = pa[u]; if (p != 0) { int heavy_in = in[adj[p][0]]; int heavy_out = out[adj[p][0]]; ll max_valv = max(Find_u.get(1, 1, n, in[p], heavy_in - 1), Find_u.get(1, 1, n, heavy_out + 1, out[p])); ll p_valv = Find_v.get(1, 1, n, in[p], in[p]); ll upd_valv = max_valv - 2 * Find_u.get(1, 1, n, in[p], in[p]) - p_valv; Find_v.update(1, 1, n, in[p], in[p], upd_valv); } u = p; } } ll get_v(int u) { ll ans = 0; while (u != 0) { ans = max(ans, Find_v.get(1, 1, n, in[head[u]], in[u] - 1)); u = head[u]; int p = pa[u]; if (p != 0) { int heavy_in = in[u]; int heavy_out = out[u]; ll max_valv = max(Find_u.get(1, 1, n, in[p], heavy_in - 1), Find_u.get(1, 1, n, heavy_out + 1, out[p])); ans = max(ans, max_valv - 2 * Find_u.get(1, 1, n, in[p], in[p])); } u = p; } return ans; } ll find_diameter() { int u = Find_u.get_maxid(1, 1, n); return Find_u.get(1, 1, n, in[u], in[u]) + get_v(u); } int main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin >> n >> q >> limW; for (int i = 1; i < n; i++) { int u, v; ll w; cin >> u >> v >> w; edges[i] = {u, v, w}; adj[u].push_back(i); adj[v].push_back(i); } dfs_sz(0, 1); dfs_head(1); for (int i = 1; i < n; i++) { if (edges[i].u == pa[edges[i].v]) swap(edges[i].u, edges[i].v); } for (auto i : dfs_order) update(edges[i].u, edges[i].w); ll last = 0; while (q--) { ll dj, ej; cin >> dj >> ej; dj = (dj + last) % (n - 1) + 1; ej = (ej + last) % limW; update(edges[dj].u, ej - edges[dj].w); edges[dj].w = ej; last = find_diameter(); cout << last << '\n'; } } /* 8 1 10 2 1 2 3 2 2 4 3 8 5 1 3 6 3 6 7 5 4 8 5 10 5 3 */
#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...