제출 #619218

#제출 시각아이디문제언어결과실행 시간메모리
619218HappyPacManDynamic Diameter (CEOI19_diameter)C++17
49 / 100
5083 ms486428 KiB
#include <bits/stdc++.h> #pragma GCC optimize("Ofast") #pragma GCC optimize("unroll-loops") #pragma GCC target("avx2") using namespace std; using ll = long long; const int maxn = 1e5 + 3; vector<pair<int,int> > adj[maxn],edges; vector<int> partOf[maxn]; vector<ll> seg[maxn],lazy[maxn]; bool isCent[maxn]; int subSz[maxn],centRoot,timer[maxn]; unordered_map<int,int> tin[maxn],tout[maxn],edgeRoot[maxn]; unordered_map<int,ll> costEdge[maxn]; ll tempResult[maxn]; priority_queue<pair<ll,int> > bestEdge[maxn],result; ll cost[maxn]; void dfsSz(int u,int p){ subSz[u] = 1; for(auto [v,w] : adj[u]){ if(v != p && !isCent[v]){ dfsSz(v,u); subSz[u] += subSz[v]; } } } int fnCent(int u,int p,int s){ for(auto [v,w] : adj[u]){ if(v != p && !isCent[v] && subSz[v] > s/2){ return fnCent(v,u,s); } } return u; } void dfsTour(int c,int u,int p){ for(auto [v,w] : adj[u]){ if(v != p && !isCent[v]){ partOf[w].emplace_back(c); tin[c][w] = timer[c]++; dfsTour(c,v,u); tout[c][w] = timer[c]++; } } } void dfsEdgeRoot(int c,int d,int u,int p){ for(auto [v,w] : adj[u]){ if(v != p && !isCent[v]){ edgeRoot[c][w] = d; dfsEdgeRoot(c,d,v,u); } } } void dfsCent(int u,int p){ dfsSz(u,p); int cent = fnCent(u,u,subSz[u]); isCent[cent] = true; if(p != -1){ centRoot = cent; } dfsTour(cent,cent,cent); for(auto [v,w] : adj[cent]){ if(!isCent[v]){ bestEdge[cent].emplace(0,w); edgeRoot[cent][w] = w; dfsEdgeRoot(cent,w,v,cent); } } seg[cent].resize(4*timer[cent]); lazy[cent].resize(4*timer[cent]); for(auto [v,w] : adj[cent]){ if(!isCent[v]){ dfsCent(v,cent); } } } // Segment Tree + Lazy Propagation void push(int c,int i){ lazy[c][i<<1] += lazy[c][i]; seg[c][i<<1] += lazy[c][i]; lazy[c][i<<1|1] += lazy[c][i]; seg[c][i<<1|1] += lazy[c][i]; lazy[c][i] = 0; } void upd(int c,int i,int l,int r,int ul,int ur,ll v){ if(ul <= l && r <= ur){ seg[c][i] += v; lazy[c][i] += v; }else if(ul > r || ur < l){ return; }else{ int m = (l+r)/2; push(c,i); upd(c,i<<1,l,m,ul,ur,v); upd(c,i<<1|1,m+1,r,ul,ur,v); seg[c][i] = max(seg[c][i<<1],seg[c][i<<1|1]); } } ll qry(int c,int i,int l,int r,int ql,int qr){ if(ql <= l && r <= qr){ return seg[c][i]; }else if(ql > r || qr < l){ return 0; }else{ int m = (l+r)/2; push(c,i); return max(qry(c,i<<1,l,m,ql,qr),qry(c,i<<1|1,m+1,r,ql,qr)); } } int32_t main(){ ios_base::sync_with_stdio(false); cin.tie(NULL); int n,q; ll w; cin >> n >> q >> w; for(int i=1;i<n;i++){ int u,v; ll w; cin >> u >> v >> w; u--; v--; adj[u].emplace_back(v,i); adj[v].emplace_back(u,i); edges.emplace_back(u,v); cost[i] = w; } dfsCent(0,-1); for(int i=1;i<n;i++){ for(int it : partOf[i]){ int z = edgeRoot[it][i]; upd(it,1,0,timer[it]-1,tin[it][i],tout[it][i]-1,cost[i]); costEdge[it][z] = qry(it,1,0,timer[it]-1,tin[it][z],tout[it][z]); bestEdge[it].emplace(costEdge[it][z],z); } } for(int i=0;i<n;i++){ vector<pair<ll,int> > best; while(!bestEdge[i].empty() && best.size() < 2){ auto [u,v] = bestEdge[i].top(); bestEdge[i].pop(); if(costEdge[i][v] == u && (best.empty() || best.back() != make_pair(u,v))){ best.emplace_back(u,v); } } ll sum = 0; for(auto it : best){ sum += it.first; } for(auto it : best){ bestEdge[i].emplace(it); } tempResult[i] = sum; result.emplace(tempResult[i],i); } ll last = 0; while(q--){ int i; ll j; cin >> i >> j; i = (i+last)%(n-1)+1; j = (j+last)%w; ll df = j-cost[i]; for(int it : partOf[i]){ int z = edgeRoot[it][i]; upd(it,1,0,timer[it]-1,tin[it][i],tout[it][i]-1,df); costEdge[it][z] = qry(it,1,0,timer[it]-1,tin[it][z],tout[it][z]); bestEdge[it].emplace(costEdge[it][z],z); vector<pair<ll,int> > best; while(!bestEdge[it].empty() && best.size() < 2){ auto [u,v] = bestEdge[it].top(); bestEdge[it].pop(); if(costEdge[it][v] == u && (best.empty() || best.back() != make_pair(u,v))){ best.emplace_back(u,v); } } ll sum = 0; for(auto it2 : best){ sum += it2.first; } for(auto it2 : best){ bestEdge[it].emplace(it2); } tempResult[it] = sum; result.emplace(tempResult[it],it); } cost[i] = j; while(true){ auto [u,v] = result.top(); if(tempResult[v] == u){ break; } result.pop(); } last = result.top().first; cout << result.top().first << "\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...