(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.

Submission #620245

#TimeUsernameProblemLanguageResultExecution timeMemory
620245ZaniteDynamic Diameter (CEOI19_diameter)C++17
100 / 100
352 ms65552 KiB
#include <bits/stdc++.h> using namespace std; using ll = long long; using pll = pair<ll, ll>; using Edge = pair<ll, pll>; #define fi first #define se second const int maxN = 1e5 + 5; const ll INF = 1e18; ll n, q, w; vector<pll> adj[maxN]; vector<Edge> edges; ll timer; ll dist[maxN], tin[maxN], tout[maxN]; vector<ll> Euler(1); void dfs(ll cur, ll par, ll cdist) { dist[cur] = cdist; Euler.push_back(cur); tin[cur] = (ll)Euler.size() - 1; for (auto &[nxt, w] : adj[cur]) { if (nxt == par) continue; dfs(nxt, cur, cdist+w); Euler.push_back(cur); } tout[cur] = (ll)Euler.size() - 1; } struct Segtree { struct Node { // max(dist[x] - 2dist[y] + dist[z]) // A = dist[x] or dist[z] // B = -2dist[y] ll A, B, AB, BA, ABA, lazy; Node() {} Node(ll val) { A = val; B = -2ll * val; AB = BA = ABA = -INF; lazy = 0; } void print() { #define _ << ' ' << cout << A _ B _ AB _ BA _ ABA _ lazy << '\n'; } }; ll sz; vector<Node> seg; Segtree(ll sz) : sz(sz) { seg.assign((sz << 2) + 1, Node()); } void updateNode(ll pos, ll val) { Node &C = seg[pos]; C.A += val; C.B -= 2ll * val; C.AB -= val; C.BA -= val; C.lazy += val; } void checkLazy(ll pos) { if (seg[pos].lazy != 0) { ll lc = pos << 1, rc = lc | 1; updateNode(lc, seg[pos].lazy); updateNode(rc, seg[pos].lazy); seg[pos].lazy = 0; } } Node merge(Node L, Node R) { Node N = Node(0); N.A = max(L.A, R.A); N.B = max(L.B, R.B); N.AB = max({ L.AB, R.AB, L.A + R.B }); N.BA = max({ L.BA, R.BA, L.B + R.A }); N.ABA = max({ L.ABA, R.ABA, L.A + R.BA, L.AB + R.A }); //cout << "Merged:\n"; //L.print(); R.print(); N.print(); return N; } void build(ll pos, ll l, ll r) { if (l == r) { //cerr << pos << ' ' << l << ' ' << Euler[l] << ' ' << dist[Euler[l]] << '\n'; seg[pos] = Node(dist[Euler[l]]); return; } ll m = (l+r) >> 1, lc = pos << 1, rc = lc | 1; build(lc, l, m); build(rc, m+1, r); seg[pos] = merge(seg[lc], seg[rc]); } void build() {build(1, 1, sz);} void update(ll pos, ll l, ll r, ll ul, ll ur, ll val) { if (l > r || ul > ur || l > ur || ul > r) return; if (ul <= l && r <= ur) { updateNode(pos, val); return; } checkLazy(pos); ll m = (l+r) >> 1, lc = pos << 1, rc = lc | 1; update(lc, l, m, ul, ur, val); update(rc, m+1, r, ul, ur, val); seg[pos] = merge(seg[lc], seg[rc]); } void update(ll ul, ll ur, ll val) {update(1, 1, sz, ul, ur, val);} ll query(ll pos, ll l, ll r, ll idx) { cerr << pos << ' ' << l << ' ' << r << ' ' << idx << '\n'; if (l == r) { return seg[pos].A; } checkLazy(pos); ll m = (l+r) >> 1, lc = pos << 1, rc = lc | 1; if (idx <= m) { return query(lc, l, m, idx); } else { return query(rc, m+1, r, idx); } } ll query() { return max({seg[1].ABA, seg[1].AB, seg[1].BA}); } void print() { for (ll i = 1; i <= sz; i++) { cout << query(1, 1, sz, i) << ' '; } cout << '\n'; } void print2() { for (ll i = 1; i <= 13; i++) {cout << i << ": "; seg[i].print();} cout << "\n"; } }; int main() { scanf("%lld %lld %lld", &n, &q, &w); for (ll a, b, c, i = 1; i < n; i++) { scanf("%lld %lld %lld", &a, &b, &c); adj[a].push_back({b, c}); adj[b].push_back({a, c}); edges.push_back({c, {a, b}}); } dfs(1, 0, 0); //for (auto i : Euler) {cout << i << ' ';} cout << '\n'; ll ES = (ll)Euler.size() - 1; /* for (ll i = 1; i <= n; i++) { cout << tin[i] << ' ' << tout[i] << ' ' << dist[i] << '\n'; } */ Segtree S(ES); S.build(); for (auto &[cw, p] : edges) { if (tin[p.se] < tin[p.fi]) {swap(p.fi, p.se);} } ll last = 0; for (ll d, e, i = 1; i <= q; i++) { scanf("%lld %lld", &d, &e); d = (d + last) % (n - 1); e = (e + last) % w; //cout << d << ' ' << e << '\n'; auto &[cw, p] = edges[d]; S.update(tin[p.se], tout[p.se], e - cw); cw = e; //S.print2(); last = S.query(); printf("%lld\n", last); } }

Compilation message (stderr)

diameter.cpp: In function 'int main()':
diameter.cpp:182:7: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  182 |  scanf("%lld %lld %lld", &n, &q, &w);
      |  ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diameter.cpp:184:8: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  184 |   scanf("%lld %lld %lld", &a, &b, &c);
      |   ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diameter.cpp:209:8: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  209 |   scanf("%lld %lld", &d, &e);
      |   ~~~~~^~~~~~~~~~~~~~~~~~~~~
#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...