Submission #1246379

#TimeUsernameProblemLanguageResultExecution timeMemory
1246379KindaGoodGamesDynamic Diameter (CEOI19_diameter)C++20
31 / 100
559 ms35256 KiB
// #pragma GCC optimize("O3, unroll-loops,Ofast") #include<bits/stdc++.h> using namespace std; #define int long long #define pii pair<int,int> #define tiii tuple<int,int,int> int INF = numeric_limits<int>::max() / 4; struct Value { int ma = -INF; int ma2 = -INF; Value() {} Value(int a) { ma = a; } Value(int a, int b) { ma = a; ma2 = b; } void add(int v) { ma += v; ma2 += v; } }; Value comb(Value a, Value b) { vector<int> r = { a.ma,a.ma2,b.ma,b.ma2 }; sort(r.rbegin(), r.rend()); return Value(r[0], r[1]); } struct SegmentTree { vector<Value> S; vector<int> lazy; int len = 1; SegmentTree(int n) { while (len < n) { len <<= 1; } S.resize(2 * len); lazy.resize(2 * len); } void upd(int i, int v) { i += len; S[i] = Value(v); for (i /= 2; i > 0; i /= 2) { S[i] = comb(S[i * 2], S[i * 2 + 1]); } } void apply1(int i, int v) { S[i].add(v); lazy[i] += v; } void push(int i) { apply1(i * 2 + 1, lazy[i]); apply1(i * 2, lazy[i]); lazy[i] = 0; } Value query(int ql, int qr, int l = 0, int r = -2, int i = 1) { if (r == -2) r = len; if (ql <= l && r <= qr) { return S[i]; } if (r <= ql || qr <= l) { return Value(); } int mid = (l + r) / 2; push(i); Value a = query(ql, qr, l, mid, i * 2); Value b = query(ql, qr, mid, r, i * 2 + 1); return comb(a, b); } void apply(int ql, int qr, int v, int l = 0, int r = -2, int i = 1) { if (r == -2) r = len; if (ql <= l && r <= qr) { apply1(i, v); return; } if (r <= ql || qr <= l) return; int mid = (l + r) / 2; push(i); apply(ql, qr, v, l, mid, i * 2); apply(ql, qr, v, mid, r, i * 2 + 1); S[i] = comb(S[i * 2], S[i * 2 + 1]); } }; vector<int> val, cost, ftree; vector<int> par, sz, depth; vector<int> start, stop; vector<vector<pii>> adj; int timer = 0; void DFS(int v, int p, int d = 0, int len = 0, int f = -1) { start[v] = timer++; depth[v] = d; sz[v] = 1; par[v] = p; ftree[v] = f; int h = -1; int s = -1; for (auto u : adj[v]) { if (u.first == p) continue; val[u.first] = len + u.second; cost[u.first] = u.second; int nf = f; if (f == -1) { nf = u.first; } DFS(u.first, v, d + 1, len + u.second, nf); sz[v] += sz[u.first]; } stop[v] = timer; } int32_t main() { ios_base::sync_with_stdio(false); cin.tie(0); int n, q, w; cin >> n >> q >> w; vector<tiii> edges(n - 1); adj.resize(n); val.resize(n); par = sz = val = depth = cost = start = stop = ftree = vector<int>(n, -1); for (int i = 0; i < n - 1; i++) { int a, b, c; cin >> a >> b >> c; a--; b--; edges[i] = { a,b,c }; adj[a].push_back({ b,c }); adj[b].push_back({ a,c }); } DFS(0, 0); val[0] = 0; cost[0] = 0; SegmentTree seg(n); for (int i = 0; i < n; i++) { seg.upd(start[i], val[i]); } int last = 0; SegmentTree seg2(adj[0].size()); map<int, int> indch; for (int i = 0; i < adj[0].size(); i++) { auto u = adj[0][i]; Value v = seg.query(start[u.first], stop[u.first]); seg2.upd(i, v.ma); indch[u.first] = i; } while (q--) { int d, e; cin >> d >> e; int edge = (last + d) % (n - 1); int weight = (e + last) % w; int a, b, c; tie(a, b, c) = edges[edge]; if (depth[a] < depth[b]) swap(a, b); int diff = weight - c; seg.apply(start[a], stop[a], diff); edges[edge] = { a,b,weight }; cost[a] = weight; auto u = ftree[a]; int ans = seg.query(start[u], stop[u]).ma; seg2.upd(indch[u], ans); int ma = 0; for (int i = 0; i < 1; i++) { Value res = Value(); res = seg2.query(0, adj[0].size()); int rem = seg.query(start[i], start[i] + 1).ma; int pv = max((res.ma + res.ma2) - (2 * rem), res.ma - rem); if (pv > ma) { ma = max({ ma, pv }); } } cout << ma << "\n"; last = ma; } }
#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...