제출 #578810

#제출 시각아이디문제언어결과실행 시간메모리
578810talant117408Dynamic Diameter (CEOI19_diameter)C++17
49 / 100
2577 ms30924 KiB
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef pair <int, int> pii; typedef pair <ll, ll> pll; #define long unsigned long #define pb push_back #define mp make_pair #define all(v) (v).begin(),(v).end() #define rall(v) (v).rbegin(),(v).rend() #define lb lower_bound #define ub upper_bound #define sz(v) int((v).size()) #define do_not_disturb ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); #define endl '\n' const int N = 1e5+7; set <pair <int, ll>> graph[N]; vector <pair <pii, ll>> edges; ll df, vf; int n, q; ll w; void find_furthest(int v, int p, ll dist = 0) { if (dist > df) { df = dist; vf = v; } for (auto to : graph[v]) { if (to.first == p) continue; find_furthest(to.first, v, dist+to.second); } } void subtask3() { for (auto to : edges) { if (to.first.first != 1) { return; } } set <pair <ll, int>, greater <pair <ll, int>>> st; for (auto to : edges) { st.insert(mp(to.second, to.first.second)); } ll last = 0; while (q--) { ll d, e; cin >> d >> e; d = (d + last) % (n - 1); e = (e + last) % w; auto &c = edges[d].second; auto b = edges[d].first.second; st.erase(st.find(mp(c, b))); c = e; st.insert(mp(c, b)); ll ans = 0; ll cnt = 0; for (auto to : st) { ans += to.first; if (++cnt > 1) break; } cout << ans << endl; last = ans; } exit(0); } void subtask4() { vector <ll> ans_for(n+1); vector <pll> mx_child(n+1), dist_child(n+1); set <pair <ll, int>, greater <pair <ll, int>>> st; for (auto to : edges) { auto a = to.first.first; auto b = to.first.second; if (!(a*2 != b || a*2+1 != b)) { return; } if (a*2 == b) dist_child[a].first = to.second; else dist_child[a].second = to.second; } for (int i = 1; i <= n; i++) { if (sz(graph[i]) == 1) { int x = i; while (x) { if (x*2 <= n) mx_child[x].first = max(mx_child[x*2].first, mx_child[x*2].second)+dist_child[x].first; if (x*2+1 <= n) mx_child[x].second = max(mx_child[x*2+1].first, mx_child[x*2+1].second)+dist_child[x].second; x >>= 1; } } } for (int i = 1; i <= n; i++) { st.insert(mp(mx_child[i].first+mx_child[i].second, i)); } ll last = 0; while (q--) { ll d, e; cin >> d >> e; d = (d + last) % (n - 1); e = (e + last) % w; auto a = edges[d].first.first, b = edges[d].first.second; int x = (b >> 1); if (a*2 == b) dist_child[a].first = e; else dist_child[a].second = e; while (x) { st.erase(st.find(mp(mx_child[x].first+mx_child[x].second, x))); if (x*2 <= n) mx_child[x].first = max(mx_child[x*2].first, mx_child[x*2].second)+dist_child[x].first; if (x*2+1 <= n) mx_child[x].second = max(mx_child[x*2+1].first, mx_child[x*2+1].second)+dist_child[x].second; st.insert(mp(mx_child[x].first+mx_child[x].second, x)); x >>= 1; } cout << (*st.begin()).first << endl; last = (*st.begin()).first; } exit(0); } ll tree[N*4], lz[N*4]; int depth[N], timer; pii range[N]; int parent[N]; int origin = 1; void push(int v, int l, int r) { if (lz[v] != 0) { tree[v] += lz[v]; if (l != r) { lz[v*2] += lz[v]; lz[v*2+1] += lz[v]; } lz[v] = 0; } } void update(int v, int l, int r, int ql, int qr, ll val) { push(v, l, r); if (ql > r || l > qr) return; if (ql <= l && r <= qr) { lz[v] += val; push(v, l, r); return; } int mid = (l+r) >> 1; update(v*2, l, mid, ql, qr, val); update(v*2+1, mid+1, r, ql, qr, val); tree[v] = max(tree[v*2], tree[v*2+1]); } ll get(int v, int l, int r, int ql, int qr) { push(v, l, r); if (ql > r || l > qr) return -1e18; if (ql <= l && r <= qr) return tree[v]; int mid = (l+r) >> 1; return max(get(v*2, l, mid, ql, qr), get(v*2+1, mid+1, r, ql, qr)); } void dfs(int v = 1, int p = 1, ll dist = 0) { range[v].first = ++timer; update(1, 1, n, timer, timer, dist); parent[v] = origin; for (auto to : graph[v]) { if (to.first == p) continue; depth[to.first] = depth[v] + 1; if (v == 1) origin = to.first; dfs(to.first, v, dist+to.second); } range[v].second = timer; } void solve() { cin >> n >> q >> w; for (int i = 0; i < n-1; i++) { int a, b; ll c; cin >> a >> b >> c; if (a > b) swap(a, b); edges.pb(mp(mp(a, b), c)); graph[a].insert(mp(b, c)); graph[b].insert(mp(a, c)); } if (n <= 5000) { ll last = 0; while (q--) { ll d, e; cin >> d >> e; d = (d + last) % (n - 1); e = (e + last) % w; auto a = edges[d].first.first, b = edges[d].first.second; auto &c = edges[d].second; graph[a].erase(graph[a].find(mp(b, c))); graph[b].erase(graph[b].find(mp(a, c))); c = e; graph[a].insert(mp(b, c)); graph[b].insert(mp(a, c)); df = vf = 0; find_furthest(1, 1); df = 0; find_furthest(vf, vf); cout << df << endl; last = df; } return; } subtask3(); subtask4(); dfs(); set <pair <ll, int>, greater <pair <ll, int>>> st; for (auto to : graph[1]) { st.insert(mp(get(1, 1, n, range[to.first].first, range[to.first].second), to.first)); } ll last = 0; while (q--) { ll d, e; cin >> d >> e; d = (d + last) % (n - 1); e = (e + last) % w; auto a = edges[d].first.first, b = edges[d].first.second; auto &c = edges[d].second; if (depth[a] > depth[b]) swap(a, b); st.erase(st.find(mp(get(1, 1, n, range[parent[b]].first, range[parent[b]].second), parent[b]))); update(1, 1, n, range[b].first, range[b].second, e-c); c = e; st.insert(mp(get(1, 1, n, range[parent[b]].first, range[parent[b]].second), parent[b])); ll res = 0; ll cnt = 0; for (auto to : st) { res += to.first; if (++cnt > 1) break; } cout << res << endl; last = res; } } int main() { do_not_disturb int t = 1; //~ cin >> t; while (t--) { solve(); } return 0; } /* */
#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...