Submission #1303568

#TimeUsernameProblemLanguageResultExecution timeMemory
1303568Faisal_SaqibDynamic Diameter (CEOI19_diameter)C++20
100 / 100
4919 ms369000 KiB
#include <bits/stdc++.h> using namespace std; typedef long long ll; #define int long long namespace dsa { struct segmenttreelazy { vector<ll> seg,lzy; int n; segmenttreelazy(int sz): n(sz){ seg.resize(sz*4,0); lzy.resize(sz*4,0); } void push(int l,int r,int v) { if(!lzy[v])return; seg[v]+=lzy[v]; int lc=v<<1,rc=lc|1; if(l!=r)lzy[lc]+=lzy[v],lzy[rc]+=lzy[v]; lzy[v]=0; } void update(int ql,int qr,ll vl,int l,int r,int v) { push(l,r,v); if(qr<l or r<ql)return; if(ql<=l and r<=qr) { lzy[v]+=vl; push(l,r,v); return; } int m=(l+r)>>1,lc=v<<1,rc=lc|1; update(ql,qr,vl,l,m,lc); update(ql,qr,vl,m+1,r,rc); seg[v]=max(seg[lc],seg[rc]); } void update(int ql,int qr,ll vl){update(ql,qr,vl,0,n-1,1);} ll get(int ql,int qr,int l,int r,int v) { push(l,r,v); if(qr<l or r<ql)return -1e18; if(ql<=l and r<=qr) { return seg[v]; } int m=(l+r)>>1,lc=v<<1,rc=lc|1; return max(get(ql,qr,l,m,lc),get(ql,qr,m+1,r,rc)); } ll get(int ql,int qr){return get(ql,qr,0,n-1,1);} }; struct centriod_decomposition{ vector<vector<pair<ll,int>>> ma; vector<bool> dead; vector<ll> sz,par,tour,lastwei; vector<vector<int>> anc,in,out,sub; vector<vector<vector<int>>> orient; vector<vector<ll>> wei; vector<segmenttreelazy> data; vector<multiset<ll>> mxd; multiset<ll> pos_ans; map<pair<int,int>,int> edge; int n,lim,cen,id=0,counter=0; centriod_decomposition(int un): n(un) { ma.resize(n+1,{}); anc.resize(n+1,{}); wei.resize(n+1,{}); orient.resize(n+1,{}); sub.resize(n+1,{}); in.resize(n+1,{}); out.resize(n+1,{}); dead.resize(n+1,false); sz.resize(n+1,1); par.resize(n+1,-1); lastwei.resize(n+1,0); } ll get() { return *rbegin(pos_ans); } void addedge(int x,int y,int w) { lastwei[counter]=w; edge[{x,y}]=edge[{y,x}]=counter++; ma[x].push_back({w,y}); ma[y].push_back({w,x}); } void dfs(int x,int p=0) { for(auto it:ma[x])if(it.second^p)dfs(it.second,x),sz[x]+=sz[it.second]; } int find_centriod(int x) { for(auto it:ma[x]) if(sz[it.second]>lim and !dead[it.second]) { sz[x]-=sz[it.second],sz[it.second]+=sz[x]; return find_centriod(it.second); } return x; } void euler_tour(int x,int p=0,int xas=-1) { for(auto it:ma[x]) if((it.second^p)!=0 and !dead[it.second]) { anc[it.second].push_back(id); in[it.second].push_back(tour.size()); sub[it.second].push_back(xas); tour.push_back(it.first); wei[it.second].push_back(it.first); if(xas==-1)euler_tour(it.second,x,it.second); else euler_tour(it.second,x,xas); out[it.second].push_back((int)(tour.size())-1); int ind=edge[{x,it.second}]; orient[ind].push_back({id,in[it.second].back(),out[it.second].back()}); // for(auto x:orient[ind])cout<<x<<' '; // cout<<endl; } } void add_seg(int x,int p=0,int xas=-1) { for(auto it:ma[x]) if((it.second^p)!=0 and !dead[it.second]) { int ind=edge[{x,it.second}]; if(!p)xas=it.second; orient[ind].back().push_back(in[xas].back()); orient[ind].back().push_back(out[xas].back()); data[anc[it.second].back()].update(in[it.second].back(),out[it.second].back(),it.first); add_seg(it.second,x,xas); if(!p) { // cout<<"For "<<id<<endl; // cout<<it.second<<' '<<data[anc[it.second].back()].get(in[it.second].back(),out[it.second].back())<<endl; mxd.back().insert(data[anc[it.second].back()].get(in[it.second].back(),out[it.second].back())); } } } void decompose(int x=1) { lim=sz[x]>>1; cen=find_centriod(x); dead[cen]=1; tour.clear(); euler_tour(cen); int szt=tour.size(); if(szt>0) { data.emplace_back(szt); mxd.emplace_back(); mxd.back().insert(0); mxd.back().insert(0); add_seg(cen); pos_ans.insert(*rbegin(mxd.back()) + *(++rbegin(mxd.back()))); id++; } for(auto it:ma[cen]) if(!dead[it.second]) decompose(it.second); } void update(int ed,ll nwei) { // cout<<endl<<"Main Update "<<ed<<' '<<nwei<<endl<<endl; for(auto igv:orient[ed]) { int i=igv[0]; int l=igv[3],r=igv[4]; int ul=igv[1],ur=igv[2]; pos_ans.erase(pos_ans.find(*rbegin(mxd[i]) + *(++rbegin(mxd[i])))); mxd[i].erase(mxd[i].find(data[i].get(l,r))); data[i].update(ul,ur,nwei-lastwei[ed]); mxd[i].insert(data[i].get(l,r)); pos_ans.insert(*rbegin(mxd[i]) + *(++rbegin(mxd[i]))); } lastwei[ed]=nwei; } void print() { for(int x=1;x<=n;x++) { cout<<"For "<<x<<endl; for(auto y:anc[x])cout<<y<<' '; cout<<endl; for(auto y:wei[x])cout<<y<<' '; cout<<endl; for(auto y:in[x])cout<<y<<' '; cout<<endl; for(auto y:out[x])cout<<y<<' '; cout<<endl; } } }; }; int32_t main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); ll n,q,w; cin>>n>>q>>w; dsa::centriod_decomposition cd(n); for(int i=1;i<n;i++) { int a,b;ll w1; cin>>a>>b>>w1; cd.addedge(a,b,w1); } cd.dfs(1); cd.decompose(1); ll lst=0; while(q--) { ll d,e; cin>>d>>e; d=(d+lst)%(n-1); e=(e+lst)%w; cd.update(d,e); lst=cd.get(); cout<<lst<<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...