#include <bits/stdc++.h>
#define ll long long int
#define mp make_pair
using namespace std;
ll N, W, Q;
vector<vector<pair<ll,ll> > > adj;
ll root = -1;
ll loggi = 30;
struct Node {
ll val=0;
ll lazy=0;
};
vector<ll> subtreesize;
vector<vector<ll> > radj;
vector<vector<ll> > whereto;
vector<vector<ll> > wheretocentr;
vector<bool> taken;
multiset<ll> totalmax;
vector<vector<ll> > treetravs;
vector<vector<Node> > segs;
vector<vector<ll> > fapps,lapps;
vector<multiset<ll> > sets;
ll getmaxvalnode(multiset<ll> &st) {
if(st.size()==0)
return 0;
if(st.size()==1) {
return *st.begin();
}
auto it = st.end();
ll res=0;
it=prev(it,1);
res+=*it;
it=prev(it,1);
res+=*it;
return res;
}
ll getsubtreesize(ll x, ll parent) {
subtreesize[x]=1;
for(auto b : adj[x]) {
if(b.first==parent||taken[b.first])
continue;
subtreesize[x]+=getsubtreesize(b.first,x);
}
return subtreesize[x];
}
ll get_centroid(ll node, ll lastsizee, ll parent) {
for(auto el :adj[node]) {
if(el.first==parent||taken[el.first])
continue;
if(subtreesize[el.first]*2>lastsizee) {
return get_centroid(el.first,lastsizee,node);
}
}
return node;
}
ll currentindex=0;
void dfs(ll x, ll superx, ll parent, ll level, ll indexwhere, ll indexwherecentr, ll valuesf) {
whereto[level][x]=indexwhere;
if(indexwherecentr!=-1) {
wheretocentr[level][x]=indexwherecentr;
}
treetravs[superx].push_back(valuesf);
fapps[level][x]=currentindex;
currentindex++;
for(auto el : adj[x]) {
ll b = el.first, w=el.second;
if(b==parent||taken[b])
continue;
dfs(b,superx,x,level,indexwhere,indexwherecentr == -1 ? b : indexwherecentr,valuesf+w);
}
treetravs[superx].push_back(valuesf);
lapps[level][x]=currentindex;
currentindex++;
}
void build(ll k, ll x, ll y, ll l, ll r, vector<Node > &seg, vector<ll> &vals) {
if(y-x<=1) {
ll threals = seg.size()/2;
if(k-threals<vals.size()) {
seg[k].val=vals[k-threals];
}
return;
}
ll d = (x+y)/2;
build(k*2,x,d,l,r,seg,vals);
build(k*2+1,d,y,l,r,seg,vals);
seg[k].val=max(seg[k*2].val,seg[k*2+1].val);
}
void checklazy(ll k, ll x, ll y, vector<Node > &seg) {
ll threals = seg.size()/2;
if(k>=threals)
return;
if(seg[k].lazy==0)
return;
ll lazy = seg[k].lazy;
seg[k].lazy=0;
seg[k*2].val+=lazy;
seg[k*2+1].val+=lazy;
seg[k*2].lazy+=lazy;
seg[k*2+1].lazy+=lazy;
}
ll getmax(ll k, ll x, ll y, ll l, ll r, vector<Node > &seg) {
checklazy(k,x,y,seg);
if(y<=l||x>=r)
return 0;
if(x>=l&&y<=r) {
return seg[k].val;
}
ll d = (x+y)/2;
return max(getmax(k*2,x,d,l,r,seg),getmax(k*2+1,d,y,l,r,seg));
}
void update(ll k, ll x, ll y, ll l, ll r, vector<Node > &seg,ll nval) {
checklazy(k,x,y,seg);
if(y<=l||x>=r)
return;
if(x>=l&&y<=r) {
seg[k].val+=nval;
seg[k].lazy=nval;
return;
}
ll d = (x+y)/2;
update(k*2,x,d,l,r,seg,nval);
update(k*2+1,d,y,l,r,seg,nval);
seg[k].val=max(seg[k*2].val,seg[k*2+1].val);
}
void processanodo(ll nodo, ll level) {
currentindex=0;
dfs(nodo,nodo,-1,level,nodo,-1,0);
ll reals=1;
taken[nodo]=true;
while(reals<treetravs[nodo].size())
reals*=2;
segs[nodo].resize(reals*2);
build(1,0,reals,0,reals,segs[nodo],treetravs[nodo]);
for(auto el : adj[nodo]) {
ll b = el.first;
if(taken[b])
continue;
ll thval = getmax(1,0,reals,fapps[level][b],lapps[level][b]+1,segs[nodo]);
sets[nodo].insert(thval);
}
totalmax.insert(getmaxvalnode(sets[nodo]));
}
void bfs() {
queue<pair<ll,ll> > q;
q.push(mp(root,0));
while(!q.empty()) {
ll x = q.front().first, level = q.front().second;
q.pop();
processanodo(x,level);
for(auto b : radj[x]) {
q.push(mp(b,level+1));
}
}
}
void modifica(ll nodoa, ll nodob, ll valore, ll nodo, ll level) {
ll nodepar = 0;
if(nodoa==nodo) {
nodepar=nodob;
} else if(nodob==nodo) {
nodepar=nodoa;
} else {
nodepar=wheretocentr[level][nodoa];
}
if(radj[nodo].size()==0)
return;
// totalmax.erase(totalmax.find(getmaxvalnode(sets[nodo])));
auto it = totalmax.find(getmaxvalnode(sets[nodo]));
totalmax.erase(it);
// cout<<fapps[level][nodepar]<<" "<<lapps[level][nodepar]<<" "<<segs[nodo].size()/2<<"\n";
ll thval = getmax(1,0,segs[nodo].size()/2,fapps[level][nodepar],lapps[level][nodepar]+1,segs[nodo]);
it = sets[nodo].find(thval);
if(it==sets[nodo].end()) {
// cout<<nodo<<" "<<nodepar<<" "<<nodoa<<" "<<thval<<"\n";
}
assert(it!=sets[nodo].end());
sets[nodo].erase(it);
int nodotouse = nodoa;
if(fapps[level][nodob]>fapps[level][nodoa]) {
nodotouse=nodob;
}
// update(1,0,segs[nodo].size()/2,fapps[level][nodotouse],lapps[level][nodotouse]+1,segs[nodo],valore);
thval = getmax(1,0,segs[nodo].size()/2,fapps[level][nodepar],lapps[level][nodepar]+1,segs[nodo]);
sets[nodo].insert(thval);
totalmax.insert(getmaxvalnode(sets[nodo]));
ll nextnode = whereto[level+1][nodoa];
if(nextnode==-1)
return;
if(whereto[level+1][nodob]==-1)
return;
modifica(nodoa,nodob,valore,nextnode,level+1);
}
void buildcentroid(ll node, ll last) {
ll centroid = get_centroid(node,getsubtreesize(node,-1),-1);
if(last==-1) {
root = centroid;
} else {
radj[last].push_back(centroid);
}
taken[centroid]=true;
for(auto el : adj[centroid]) {
ll b = el.first;
if(taken[b])
continue;
buildcentroid(b,centroid);
}
}
int main() {
// freopen("input.txt","r",stdin);
// freopen("output.txt","w",stdout);
cin>>N>>Q>>W;
adj.resize(N);
vector<pair<pair<ll,ll>,ll> > edges;
for(ll i=0;i<N-1;i++) {
ll a,b,c;
cin>>a>>b>>c;
a--;
b--;
edges.push_back(mp(mp(a,b),c));
adj[a].push_back(mp(b,c));
adj[b].push_back(mp(a,c));
}
radj.resize(N);
whereto.assign(loggi,vector<ll> (N,-1));
wheretocentr.resize(loggi, vector<ll> (N));
fapps.resize(loggi, vector<ll> (N));
lapps.resize(loggi, vector<ll> (N));
segs.resize(N);
sets.resize(N);
treetravs.resize(N);
subtreesize.resize(N);
taken.resize(N);
buildcentroid(0,-1);
taken.clear();
taken.resize(N);
bfs();
ll last=0;
for(ll i=0;i<Q;i++) {
ll d, e;
cin>>d>>e;
d=(d+last)%(N-1);
e=(e+last)%W;
ll nodea = edges[d].first.first, nodeb=edges[d].first.second;
modifica(nodea,nodeb,-edges[d].second,root,0);
modifica(nodea,nodeb,e,root,0);
edges[d].second=e;
auto it = totalmax.end();
it=prev(it,1);
last=*it;
cout<<last<<"\n";
}
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |