#include <bits/stdc++.h>
using namespace std;
#define int ll
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
vector<vector<int>> G;
vector<bool> in_c;
vector<int> siz;
void dfs(int v, int p) {
    siz[v] = 1;
    for (int u : G[v]) {
        if (in_c[u] || u == p)
            continue;
        dfs(u, v);
        siz[v] += siz[u];
    }
}
int get_cent(int v, int p, int N) {
    for (int u : G[v]) {
        if (in_c[u] || u == p)
            continue;
        if (siz[u] > N / 2)
            return get_cent(u, v, N);
    }
    return v;
}
multiset<ll, greater<>> CS;
void erase(ll w) {
    CS.erase(CS.find(w));
}
void insert(ll w) {
    CS.insert(w);
}
struct lvl {
    struct node {
        map<int, int> in, out;
        vector<ll> st, add;
        int n;
        void update(int i, int l, int r, int tl, int tr, ll w) {
            if (l >= r)
                return;
            if (l == tl && r == tr)
                add[i] += w;
            else {
                int tm = (tl + tr) / 2;
                update(2 * i, l, min(tm, r), tl, tm, w),
                update(2 * i + 1, max(l, tm), r, tm, tr, w);
            }
            st[i] = add[i] + (tl + 1 == tr ? 0 : max(st[2 * i], st[2 * i + 1]));
        }
        void update_edge(int u, int v, ll w) {
            if (in[u] > in[v])
                swap(u, v);
            update(1, in[v], out[v], 0, n, w);
        }
        void dfs(int v, int p) {
            in[v] = n++;
            for (int u : G[v]) {
                if (in_c[u] || u == p)
                    continue;
                dfs(u, v);
            }
            out[v] = n;
        }
        void init(int v, int p) {
            dfs(v, p);
            int N = 1;
            while (N < n)
                N *= 2;
            st.resize(2 * N);
            add.resize(2 * N);
        }
    };
    multiset<ll, greater<>> S;
    ll calc() {
        if (S.empty())
            return 0;
        if (S.size() == 1)
            return *S.begin();
        return *S.begin() + *next(S.begin());
    }
    map<int, node*> nodes;
    int d;
    void init(int v, int _d) {
        d = _d;
        nodes[v] = nullptr;
        for (int u : G[v]) {
            if (in_c[u])
                continue;
            node *cur = new node();
            cur->init(u, v);
            for (auto [v, jnk] : cur->in)
                nodes[v] = cur;
            S.insert(0);
        }
        insert(calc());
    }
    void update_edge(int u, int v, ll w) {
        erase(calc());
        if (!nodes[v])
            swap(u, v);
        S.erase(S.find(nodes[v]->st[1]));
        if (nodes[u] && nodes[v])
            nodes[v]->update_edge(u, v, w);
        else
            nodes[v]->st[1] += w, nodes[v]->add[1] += w;
        S.insert(nodes[v]->st[1]);
        insert(calc());
    }
};
vector<lvl> dcmp;
vector<int> par;
void cent_decomposition(int v, int d = 0) {
    dfs(v, -1);
    int c = get_cent(v, -1, siz[v]);
    dcmp[c].init(c, d);
    in_c[c] = true;
    for (int u : G[c]) {
        if (in_c[u])
            continue;
        par[u] = c;
        cent_decomposition(u, d + 1);
    }
}
vector<pair<pii, ll>> E;
void update_edge(int i, ll w) {
    auto [p, pw] = E[i];
    auto [u, v] = p;
    ll diff = w - pw;
    E[i].second = w;
    int c = dcmp[u].d < dcmp[v].d ? u : v;
    while (c) {
        dcmp[c].update_edge(u, v, diff);
        c = par[c];
    }
}
int32_t main() {
    cin.tie(nullptr)->sync_with_stdio(false);
    int n, q, w;
    cin >> n >> q >> w;
    G.resize(n + 1);
    in_c.resize(n + 1);
    siz.resize(n + 1);
    dcmp.resize(n + 1);
    par.resize(n + 1);
    E.resize(n);
    vector<ll> qu(n);
    for (int i = 1; i < n; i++) {
        int a, b;
        ll c;
        cin >> a >> b >> c;
        E[i] = {{a, b}, 0};
        qu[i] = c;
        G[a].push_back(b);
        G[b].push_back(a);
    }
    cent_decomposition(1);
    for (int i = 1; i < n; i++) {
        update_edge(i, qu[i]);
    }
    ll last = 0;
    while (q--) {
        int d;
        ll e;
        cin >> d >> e;
        d = (last + d) % (n - 1);
        e = (last + e) % w;
        update_edge(d + 1, e);
        last = *CS.begin();
        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... |