This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include<bits/stdc++.h>
using namespace std;
#define int ll
#define fi first
#define se second
#define pb push_back
#define all(x) x.begin(),x.end()
#define for1(i,x,n) for(int i=x;i<=n;i++)
#define for2(i,x,n) for(int i=x;i>=n;i--)
typedef long long ll;
typedef pair<int,int> pii;
const ll maxn = 1e5 + 3;
const ll mod = 1e9 + 7;
const ll inf = 1e18;
int n,q;
int mx[maxn*4];
int sz[maxn],dep[maxn],in[maxn],out[maxn],Time,uu[maxn],vv[maxn],w[maxn],a[maxn],b[maxn],k[maxn],ans[maxn];
bool used[maxn],dd[maxn];
vector<int> adj[maxn],qr[maxn],go[maxn];
void Udp(int u,int v,int id=1,int l=1,int r=n)
{
if (l==r)
{
mx[id]=v;
return;
}
int mid=l+r>>1;
if (u<=mid) Udp(u,v,id*2,l,mid);
else Udp(u,v,id*2+1,mid+1,r);
mx[id]=max(mx[id*2],mx[id*2+1]);
}
struct T
{
int cen,up,dep,in,out;
};
vector<T> L[maxn];
struct Node
{
pii x, y;
};
Node Merge(Node a,Node b)
{
if (a.x<b.x) swap(a,b);
if (a.x.se!=b.x.se) a.y=max(a.y,b.x);
if (a.x.se!=b.y.se) a.y=max(a.y,b.y);
return a;
}
struct segtree
{
int nn;
vector<Node> st;
vector<int> lazy;
void init(int x)
{
nn=x;
st.resize(nn*4+2,(Node){{-1,-1},{-1,-1}});
lazy.resize(nn*4+2,0);
}
void push(int id)
{
int& val=lazy[id];
if (st[id*2].x.fi!=-1) st[id*2].x.fi+=val;
if (st[id*2].y.fi!=-1) st[id*2].y.fi+=val;
lazy[id*2]+=val;
if (st[id*2+1].x.fi!=-1) st[id*2+1].x.fi+=val;
if (st[id*2+1].y.fi!=-1) st[id*2+1].y.fi+=val;
lazy[id*2+1]+=val;
val=0;
}
void Update(int u,pii v,int id,int l,int r)
{
if (l==r)
{
st[id]={v,{-1,-1}};
return;
}
if (lazy[id]) push(id);
int mid=l+r>>1;
if (u<=mid) Update(u,v,id*2,l,mid);
else Update(u,v,id*2+1,mid+1,r);
st[id]=Merge(st[id*2],st[id*2+1]);
}
void Update2(int u,int v,int val,int id,int l,int r)
{
if (u>r || v<l) return;
if (u<=l && r<=v)
{
if (st[id].x.fi!=-1) st[id].x.fi+=val;
if (st[id].y.fi!=-1) st[id].y.fi+=val;
lazy[id]+=val;
return;
}
if (lazy[id]) push(id);
int mid=l+r>>1;
Update2(u,v,val,id*2,l,mid);
Update2(u,v,val,id*2+1,mid+1,r);
st[id]=Merge(st[id*2],st[id*2+1]);
}
}tree[maxn];
void dfs_sz(int u,int pre)
{
sz[u]=1;
for(int i: adj[u])
{
int v=u^uu[i]^vv[i];
if (v==pre || used[v]) continue;
dfs_sz(v,u);
sz[u]+=sz[v];
}
}
int Find_cen(int u,int pre,int treesz)
{
for(int i:adj[u])
{
int v=u^uu[i]^vv[i];
if (v==pre || used[v]) continue;
if (sz[v]*2>treesz) return Find_cen(v,u,treesz);
}
return u;
}
void dfs_dep(int u,int pre)
{
for(int i: adj[u])
{
int v=u^uu[i]^vv[i];
if (v==pre || used[v]) continue;
dep[v]=dep[u]+w[i];
// cerr<<" d "<<v<<' '<< dep[v]<<'\n';
dfs_dep(v,u);
}
}
void initial(int u,int pre,int cen,int rt)
{
in[u]=++Time;
for(int i: adj[u])
{
int v=u^uu[i]^vv[i];
if (v==pre || used[v]) continue;
initial(v,u,cen,rt);
}
out[u]=Time;
L[u].pb({cen,rt,dep[u],in[u],out[u]});
}
void centroid(int u)
{
dfs_sz(u,-1);
if (sz[u]==1) return;
// cerr<< sz[u]<<'\n';
u=Find_cen(u,-1,sz[u]);
// cerr<<"cen "<< u<<"\n";
used[u]=1;
dep[u]=0;
dfs_dep(u,-1);
Time=1;
for(int i:adj[u])
{
int v=u^uu[i]^vv[i];
if (used[v]) continue;
initial(v,u,u,v);
}
L[u].pb({u,u,0,1,Time});
tree[u].init(Time);
for(int i: adj[u])
{
int v=u^uu[i]^vv[i];
if (used[v]) continue;
centroid(v);
}
}
void Add(int u)
{
// cerr<< "add dinh "<<u<<' '<<L[u].size()<<'\n';
for(auto x:L[u])
{
// cerr<< x.cen<<' '<<x.up<<' '<< x.dep<<'\n';
tree[x.cen].Update(x.in,{x.dep,x.up},1,1,tree[x.cen].nn);
if (tree[x.cen].st[1].y.fi!=-1) Udp(x.cen,tree[x.cen].st[1].x.fi+tree[x.cen].st[1].y.fi);
}
// cerr<<tree[2].st[1].x.fi<<' '<<tree[2].st[1].y.fi<<'\n';
}
void sol()
{
int WW;
cin >> n>> q>>WW;
for1(i,1,n-1)
{
cin >> uu[i]>>vv[i]>>w[i];
adj[uu[i]].pb(i);
adj[vv[i]].pb(i);
}
centroid(1);
for1(i,1,n) Add(i);
int last=0,d=0,e=0;
for1(i,1,q)
{
cin >> d>>e;
d=(d+last)%(n-1);
e=(e+last)%WW;
int j=d+1;
for(auto x: L[uu[j]])
{
for(auto y:L[vv[j]])
{
if (x.cen==y.cen)
{
T g;
if (x.in<y.in) g=y;
else g=x;
tree[g.cen].Update2(g.in,g.out,e-w[j],1,1,tree[x.cen].nn);
if (tree[x.cen].st[1].y.fi!=-1) Udp(x.cen,tree[x.cen].st[1].x.fi+tree[x.cen].st[1].y.fi);
}
}
}
w[j]=e;
last=mx[1];
cout << last<<'\n';
}
}
int32_t main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int t=1;//cin >> t;
while (t--) sol();
}
/*
5
5 3 5 3 5
10 1 20 1 20
*/
Compilation message (stderr)
diameter.cpp: In function 'void Udp(ll, ll, ll, ll, ll)':
diameter.cpp:30:14: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
30 | int mid=l+r>>1;
| ~^~
diameter.cpp: In member function 'void segtree::Update(ll, pii, ll, ll, ll)':
diameter.cpp:85:18: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
85 | int mid=l+r>>1;
| ~^~
diameter.cpp: In member function 'void segtree::Update2(ll, ll, ll, ll, ll, ll)':
diameter.cpp:101:18: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
101 | int mid=l+r>>1;
| ~^~
# | 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... |