Submission #276006

#TimeUsernameProblemLanguageResultExecution timeMemory
276006theStaticMindDynamic Diameter (CEOI19_diameter)C++14
31 / 100
931 ms30944 KiB
#include<bits/stdc++.h> #define pb push_back #define ii pair<int,int> #define all(x) (x).begin(),(x).end() #define sz(x) ((int)(x).size()) #define INF 100000000000000000 #define modulo 1000000007 #define mod 998244353 #define int long long int using namespace std; int S; struct MaxSeg{ vector<int> seg; vector<int> lazy; MaxSeg(int N); void build(); void push(int j); void pull(int j); void rangeupdate(int j, int x, int y, int l, int r, int v); int rangequery(int j, int x, int y, int l, int r); } seg(100005); int n; vector<ii> adj[100005]; vector<ii> edge; int anc[100005]; int depth[100005]; int T[100005]; int X[100005]; multiset<int> data; map<int, int> ptr; int getedge(int x, int y){ return lower_bound(all(adj[x]), ii{y, -1}) - adj[x].begin(); } void update(int y){ data.erase(data.lower_bound(ptr[y])); ptr[y] = seg.rangequery(1, 0, S - 1, T[y], X[y]); data.insert(ptr[y]); } void init(int x, int pre){ static int time = 1; T[x] = time++; if(pre == 1)anc[x] = x; for(auto p : adj[x]){ int y = p.first; if(y == pre) continue; anc[y] = anc[x]; depth[y] = depth[x] + 1; init(y, x); } X[x] = time - 1; } vector<int> dp(100005, 0); void naive(int x, int pre){ for(auto p : adj[x]){ int y = p.first; if(y == pre) continue; dp[y] = dp[x] + p.second; naive(y, x); } } int32_t main(){ ios_base::sync_with_stdio(false); cin.tie(NULL); int q, W; cin >> n >> q >> W; for(int i = 0; i < n - 1; i++){ int x, y, z; cin >> x >> y >> z; adj[x].pb({y, z}); adj[y].pb({x, z}); edge.pb({x, y}); } for(int i = 1; i <= n; i++){ sort(all(adj[i])); } init(1, 0); naive(1, 0); for(int i = 1; i <= n; i++){ seg.rangeupdate(1, 0, S - 1, T[i], T[i], dp[i]); } int last = 0; for(auto p : adj[1]){ ptr[p.first] = seg.rangequery(1, 0, S - 1, T[p.first], X[p.first]); data.insert(ptr[p.first]); } while(q--){ ii p; cin >> p.first >> p.second; p.first = (p.first + last) % (n - 1); p.second = (p.second + last) % W; int x = edge[p.first].first; int y = edge[p.first].second; int z = p.second; if(depth[x] > depth[y]) swap(x, y); seg.rangeupdate(1, 0, S - 1, T[y], X[y], z - adj[x][getedge(x, y)].second); update(anc[y]); adj[x][getedge(x, y)].second = z; adj[y][getedge(y, x)].second = z; last = *data.rbegin(); if(sz(data) > 1) last += *++data.rbegin(); cout << last << "\n"; } } MaxSeg::MaxSeg(int N){ seg= vector<int>(N, 0); build(); } void MaxSeg::build(){ S = 1 << (int)ceil(log2(sz(seg))); while(sz(seg) != S) seg.pb(0); reverse(all(seg)); for(int i = 1; i < sz(seg); i += 2) seg.pb(max(seg[i - 1], seg[i])); seg.pb(0); reverse(all(seg)); lazy = vector<int> (sz(seg), 0); } void MaxSeg::push(int j){ if(j < sz(seg)){ seg[j] += lazy[j]; if(j * 2 < sz(seg)){ lazy[j*2] += lazy[j]; lazy[j*2+1] += lazy[j]; } lazy[j] = 0; } } void MaxSeg::pull(int j){ push(j); push(j*2); push(j*2+1); if(j * 2 < sz(seg)){ seg[j] = max(seg[j*2], seg[j*2+1]); } } void MaxSeg::rangeupdate(int j, int x, int y, int l, int r, int v){ if(y < l || r < x) return; push(j); if(l <= x && y <= r){ lazy[j] += v; } else{ rangeupdate(j*2,x,(x+y)/2,l,r,v); rangeupdate(j*2+1,(x+y)/2+1,y,l,r,v); } pull(j); } int MaxSeg::rangequery(int j, int x, int y, int l, int r){ if(y < l || r < x) return 0; push(j); if(l <= x && y <= r){ return seg[j]; } else{ return max( rangequery(j*2,x,(x+y)/2,l,r), rangequery(j*2+1,(x+y)/2+1,y,l,r) ); } }
#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...