#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pii pair <int, int>
#define pil pair <int, ll>
#define fi first
#define se second
#define mp make_pair
#define isz(a) (int)(a).size()
const int NM = 1e5;
struct edge{
int u, v;
ll l;
};
int n, q;
edge E[NM+5];
ll w;
vector <pil> adj[NM+5];
int parent_cen[NM+5], num[NM+5], fnum[NM+5], sz[NM+5], timer;
bool del[NM+5];
vector <int> tmp, vlist[NM+5], tin[NM+5], tout[NM+5], tour[NM+5], f[NM+5];
vector <ll> d[NM+5], st[NM+5], lazy[NM+5];
multiset <ll, greater <ll> > mxf[NM+5], S;
void dfs_sz(int u, int p){
tmp.push_back(u);
sz[u] = 1;
for (pil _ : adj[u]){
int v = _.fi;
if (v == p || del[v]) continue;
dfs_sz(v, u);
sz[u] += sz[v];
}
}
int dfs_fc(int rt, int u, int p){
for (pil _ : adj[u]){
int v = _.fi;
if (v == p || del[v]) continue;
if (sz[v] > sz[rt]/2) return dfs_fc(rt, v, u);
}
return u;
}
void dfs_dp(int rt, int u, int p, int pos_u){
if (u == rt){
f[rt][pos_u] = -1;
d[rt][pos_u] = 0;
}
tin[rt][pos_u] = timer++;
tour[rt][timer-1] = pos_u;
for (pil _ : adj[u]){
int v = _.fi;
ll l = _.se;
if (v == p || del[v]) continue;
int pos_v = lower_bound(vlist[rt].begin(), vlist[rt].end(), v)-vlist[rt].begin();
if (u == rt) f[rt][pos_v] = pos_v;
else f[rt][pos_v] = f[rt][pos_u];
d[rt][pos_v] = d[rt][pos_u]+l;
dfs_dp(rt, v, u, pos_v);
}
tout[rt][pos_u] = timer-1;
}
void build(int rt, int id, int l, int r){
if (l == r){
st[rt][id] = d[rt][tour[rt][l]];
return;
}
int mid = (l+r)/2;
build(rt, 2*id, l, mid);
build(rt, 2*id+1, mid+1, r);
st[rt][id] = max(st[rt][2*id], st[rt][2*id+1]);
}
void down(int rt, int id){
st[rt][2*id] += lazy[rt][id], st[rt][2*id+1] += lazy[rt][id];
lazy[rt][2*id] += lazy[rt][id], lazy[rt][2*id+1] += lazy[rt][id];
lazy[rt][id] = 0;
}
void update(int rt, int id, int l, int r, int u, int v, ll val){
if (u > v || v < l || u > r) return;
if (l >= u && r <= v){
st[rt][id] += val;
lazy[rt][id] += val;
return;
}
down(rt, id);
int mid = (l+r)/2;
update(rt, 2*id, l, mid, u, v, val);
update(rt, 2*id+1, mid+1, r, u, v, val);
st[rt][id] = max(st[rt][2*id], st[rt][2*id+1]);
}
ll get(int rt, int id, int l, int r, int u, int v){
if (u > v || v < l || u > r) return -1;
if (l >= u && r <= v) return st[rt][id];
down(rt, id);
int mid = (l+r)/2;
return max(get(rt, 2*id, l, mid, u, v), get(rt, 2*id+1, mid+1, r, u, v));
}
ll get_diameter(int rt){
if (mxf[rt].empty()) return 0;
if (isz(mxf[rt]) == 1) return *mxf[rt].begin();
return *mxf[rt].begin() + *(next(mxf[rt].begin()));
}
void decompose(int u, int p){
tmp.clear();
dfs_sz(u, -1);
u = dfs_fc(u, u, -1);
parent_cen[u] = p;
del[u] = 1;
num[u] = isz(tmp);
sort(tmp.begin(), tmp.end());
vlist[u] = tmp;
tin[u].resize(num[u]); tout[u].resize(num[u]); tour[u].resize(num[u]);
f[u].resize(num[u]);
d[u].resize(num[u]);
timer = 0;
dfs_dp(u, u, -1, lower_bound(vlist[u].begin(), vlist[u].end(), u)-vlist[u].begin());
st[u].resize(4*num[u]+1);
lazy[u].assign(4*num[u]+1, 0LL);
build(u, 1, 0, num[u]-1);
mxf[u].clear();
for (int i = 0; i < num[u]; i++){
if (f[u][i] != i) continue;
mxf[u].insert(get(u, 1, 0, num[u]-1, tin[u][i], tout[u][i]));
}
S.insert(get_diameter(u));
for (pil _ : adj[u]){
int v = _.fi;
if (del[v]) continue;
decompose(v, u);
}
}
void add(int rt, int u, int v, ll val){
S.erase(S.find(get_diameter(rt)));
int pos_u = lower_bound(vlist[rt].begin(), vlist[rt].end(), u)-vlist[rt].begin();
int pos_v = lower_bound(vlist[rt].begin(), vlist[rt].end(), v)-vlist[rt].begin();
if (tin[rt][pos_u] < tin[rt][pos_v]){
ll pre = get(rt, 1, 0, num[rt]-1, tin[rt][f[rt][pos_v]], tout[rt][f[rt][pos_v]]);
update(rt, 1, 0, num[rt]-1, tin[rt][pos_v], tout[rt][pos_v], val);
ll cur = get(rt, 1, 0, num[rt]-1, tin[rt][f[rt][pos_v]], tout[rt][f[rt][pos_v]]);
if (pre != cur){
mxf[rt].erase(mxf[rt].find(pre));
mxf[rt].insert(cur);
}
}
else{
ll pre = get(rt, 1, 0, num[rt]-1, tin[rt][f[rt][pos_u]], tout[rt][f[rt][pos_u]]);
update(rt, 1, 0, num[rt]-1, tin[rt][pos_u], tout[rt][pos_u], val);
ll cur = get(rt, 1, 0, num[rt]-1, tin[rt][f[rt][pos_u]], tout[rt][f[rt][pos_u]]);
if (pre != cur){
mxf[rt].erase(mxf[rt].find(pre));
mxf[rt].insert(cur);
}
}
S.insert(get_diameter(rt));
}
signed main(){
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> n >> q >> w;
for (int i = 0; i < n-1; i++){
cin >> E[i].u >> E[i].v >> E[i].l;
adj[E[i].u].push_back(mp(E[i].v, E[i].l));
adj[E[i].v].push_back(mp(E[i].u, E[i].l));
}
decompose(1, -1);
ll lst = 0;
while (q--){
int d; ll e;
cin >> d >> e;
d = (d+lst)%(n-1);
e = (e+lst)%w;
if (num[E[d].u] < num[E[d].v]) swap(E[d].u, E[d].v);
for (int rt = E[d].u; rt != -1; rt = parent_cen[rt])
add(rt, E[d].u, E[d].v, e-E[d].l);
E[d].l = e;
lst = *S.begin();
cout << lst << '\n';
}
return 0;
}
# | 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... |