(UPD: 2024-12-04 14:48 UTC) Judge is not working due to Cloudflare incident. (URL) We can do nothing about it, sorry. After the incident is resolved, we will grade all submissions.

제출 #424400

#제출 시각아이디문제언어결과실행 시간메모리
424400HegdahlDynamic Diameter (CEOI19_diameter)C++17
100 / 100
3477 ms52508 KiB
#include <bits/stdc++.h> #define ar array using namespace std; using ll = long long; const int mxN = 1e5; vector<ar<ll, 2>> g[mxN]; int frst[mxN], last[mxN]; ll depth[mxN]; vector<int> order; void dfs(int cur, int prv, ll d) { frst[cur] = (int)order.size(); last[cur] = (int)order.size(); depth[cur] = d; order.push_back(cur); for (auto [nxt, w] : g[cur]) { if (nxt == prv) continue; dfs((int)nxt, cur, d+w); last[cur] = (int)order.size(); order.push_back(cur); } } const ll INF = 1LL<<60; struct S { ll lmin, lmax, mmin, rmax, rmin, longest; S() : lmin(INF), lmax(INF), mmin(INF), rmax(INF), rmin(INF), longest(INF) {} S(ll d) : lmin(d), lmax(d), mmin(d), rmax(d), rmin(d), longest(0) {} S(ll lm, ll l, ll m, ll r, ll rm) : lmin(lm), lmax(l), mmin(m), rmax(r), rmin(rm), longest(l + r - 2*m) {} bool operator<(const S &o) const { return longest < o.longest; } void pull(S l, S r) { if (l.lmin == INF) return void(*this = r); if (r.lmin == INF) return void(*this = l); vector<ll> v { l.lmin, l.lmax, l.mmin, l.rmax, l.rmin, r.lmin, r.lmax, r.mmin, r.rmax, r.rmin, }; vector<S> alts; for (int i = 1; i < 9; ++i) { for (int j = i+1; j < 9; ++j) { ll premin = INF; for (int k = 0; k <= i; ++k) premin = min(premin, v[k]); ll midmin = INF; for (int k = i; k <= j; ++k) midmin = min(midmin, v[k]); ll sufmin = INF; for (int k = j; k < 10; ++k) sufmin = min(sufmin, v[k]); alts.emplace_back(premin, v[i], midmin, v[j], sufmin); } } *this = *max_element(alts.begin(), alts.end()); } }; struct F { ll s = 0; void apply(F &f) { f.s += s; } void apply(S &v) { v.lmin += s; v.lmax += s; v.mmin += s; v.rmax += s; v.rmin += s; } }; const int mxL = mxN + mxN-1; const int offset = 2<<__lg(mxL-1); S values[2*offset]; F lazy[offset]; int push(int I, int l, int r) { lazy[I].apply(values[2*I]); lazy[I].apply(values[2*I+1]); if (2*I < offset) { lazy[I].apply(lazy[2*I]); lazy[I].apply(lazy[2*I+1]); } lazy[I] = F(); return l + (r-l+1)/2; } S qry(int i, int j, int I = 1, int l = 0, int r = offset-1) { assert(!(i > r || j < l)); if (i <= l && j >= r) return values[I]; int mid = push(I, l, r); S res; res.pull( (i<mid?qry(i, j, 2*I, l, mid-1):S()), (j>=mid?qry(i, j, 2*I+1, mid, r):S()) ); return res; } void upd(int i, int j, F f, int I = 1, int l = 0, int r = offset-1) { assert(!(i > r || j < l)); if (i <= l && j >= r) { f.apply(values[I]); if (I < offset) f.apply(lazy[I]); return; } int mid = push(I, l, r); if (i < mid) upd(i, j, f, 2*I, l, mid-1); if (j >= mid) upd(i, j, f, 2*I+1, mid, r); values[I].pull(values[2*I], values[2*I+1]); } int main() { cin.tie(0)->sync_with_stdio(0); int n, q; ll mxw; cin >> n >> q >> mxw; vector<ar<ll, 3>> e(n-1); for (auto &[i, j, w] : e) { cin >> i >> j >> w; --i, --j; g[i].push_back({j, w}); g[j].push_back({i, w}); } dfs(0, -1, 0); assert((int)order.size() == 2*n-1); assert(offset >= order.size()); for (int i = 0; i < (int)order.size(); ++i) values[offset+i] = S(depth[order[i]]); for (int i = offset-1; i > 0; --i) values[i].pull(values[2*i], values[2*i+1]); ll ans = 0; for (int qq = 0; qq < q; ++qq) { int ei; ll w; cin >> ei >> w; ei = int((ei+ans)%(n-1)); w = (w+ans)%mxw; auto &[i, j, pw] = e[ei]; if (depth[i] > depth[j]) swap(i, j); ll change = w-pw; pw = w; upd(frst[j], last[j], {change}); ans = qry(0, offset-1).longest; cout << ans << '\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...