(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 #856525

#TimeUsernameProblemLanguageResultExecution timeMemory
856525hockyDynamic Diameter (CEOI19_diameter)C++14
100 / 100
347 ms64528 KiB
#include "bits/stdc++.h" using namespace std; const int LIM = 100000; #define fi first #define se second typedef long long LL; typedef pair<LL,LL> PLL; namespace DynamicDiameter { vector <PLL> edge[LIM + 5]; int event[2 * LIM + 5]; int dfsTime = 0; LL weights[LIM + 5], depth[LIM + 5]; PLL order[LIM + 5]; void eulerTour(int pos, int par = -1) { dfsTime++; order[pos].fi = dfsTime; event[dfsTime] = pos; for (auto &nx: edge[pos]) { if (nx.fi == par) continue; depth[nx.fi] = depth[pos] + nx.se; weights[nx.fi] = nx.se; eulerTour(nx.fi, pos); dfsTime++; event[dfsTime] = pos; } order[pos].se = dfsTime; return; } const LL INF = 1e14; // Segment Tree starts here struct Node{ LL maxDepth = -INF, minDepth = INF; LL leftMax = -INF, rightMax = -INF; LL diameter = 0; LL lazy; }; Node segt[8 * LIM + 5]; void pushDown(int rangeL = 1, int rangeR = dfsTime, int idx = 1){ if(segt[idx].lazy == 0) return; auto &val = segt[idx].lazy; segt[idx].maxDepth += val; segt[idx].minDepth += val; segt[idx].leftMax -= val; segt[idx].rightMax -= val; if(rangeL != rangeR){ segt[idx * 2].lazy += val; segt[idx * 2 + 1].lazy += val; } val = 0; return; } void merge(Node &head, Node &l, Node &r){ head.maxDepth = max(l.maxDepth, r.maxDepth); head.minDepth = min(l.minDepth, r.minDepth); head.leftMax = max(l.leftMax, r.leftMax); head.leftMax = max(head.leftMax, l.maxDepth - 2 * r.minDepth); head.rightMax = max(l.rightMax, r.rightMax); head.rightMax = max(head.rightMax, r.maxDepth - 2 * l.minDepth); head.diameter = max(l.diameter, r.diameter); head.diameter = max(head.diameter, l.maxDepth + r.rightMax); head.diameter = max(head.diameter, r.maxDepth + l.leftMax); //~ cout << head.maxDepth << " " << head.minDepth << " " << head.leftMax << " " << head.rightMax << " " << head.diameter << endl; } void build(int rangeL = 1, int rangeR = dfsTime, int idx = 1){ //~ cout << rangeL << " " << rangeR << " " << idx << endl; if(rangeL == rangeR){ segt[idx].minDepth = segt[idx].maxDepth = depth[event[rangeL]]; segt[idx].leftMax = segt[idx].rightMax = -depth[event[rangeL]]; return; } int mid = (rangeL + rangeR) >> 1; build(rangeL, mid, idx * 2); build(mid + 1, rangeR, idx * 2 + 1); merge(segt[idx], segt[idx * 2], segt[idx * 2 + 1]); } void update(int queryL, int queryR, LL val, int rangeL = 1, int rangeR = dfsTime, int idx = 1){ pushDown(rangeL, rangeR, idx); if(rangeR < queryL) return; if(queryR < rangeL) return; if(queryL <= rangeL && rangeR <= queryR){ segt[idx].lazy = val; pushDown(rangeL, rangeR, idx); return; } int mid = (rangeL + rangeR) >> 1; update(queryL, queryR, val, rangeL, mid, idx * 2); update(queryL, queryR, val, mid + 1, rangeR, idx * 2 + 1); merge(segt[idx], segt[idx * 2], segt[idx * 2 + 1]); return; } } using namespace DynamicDiameter; int main() { cin.tie(0) -> sync_with_stdio(0); cout.tie(0); LL n, q, w; cin >> n >> q >> w; vector <PLL> edges(n - 1); for (int i = 0; i < n - 1; i++) { LL c; cin >> edges[i].fi >> edges[i].se >> c; edge[edges[i].fi].emplace_back(edges[i].se, c); edge[edges[i].se].emplace_back(edges[i].fi, c); } eulerTour(1); //~ for(int i = 1;i <= dfsTime;i++) cout << event[i] << " "; //~ cout << endl; //~ for(int i = 1;i <= n;i++) cout << i << " " << order[i].fi << " " << order[i].se << endl; build(); LL ans = 0; //~ cout << segt[1].diameter << endl; //~ return 0; while(q--){ LL d, e; cin >> d >> e; d = (d + ans) % (n - 1); e = (e + ans) % w; auto &edge = edges[d]; if(order[edge.fi].fi > order[edge.se].fi) { swap(edge.fi, edge.se); } // Update the segment tree //~ cout << e - weights[edge.se] << endl; //~ cout << segt[1].diameter << endl; update(order[edge.se].fi, order[edge.se].se, e - weights[edge.se]); weights[edge.se] = e; pushDown(); ans = segt[1].diameter; cout << ans << endl; } }
#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...