#include <bits/stdc++.h>
#define int long long
using namespace std;
const int nmax = 1e5;
struct Edge
{
    int x, y, c;
};
int n, q, w;
Edge e[nmax + 5];
vector<pair<int,int>> G[nmax + 5];
int l[nmax + 5];
int t[nmax + 5];
int p[nmax + 5], u[nmax + 5];
int r[nmax + 5];
pair<int,int> ai[4 * nmax + 5];
int lazy[4 * nmax + 5];
pair<int,int> Merge(pair<int,int> a, pair<int,int> b)
{
    if(a > b)
    {
        return a;
    }
    return b;
}
void init(int nod, int a, int b)
{
    if(a == b)
    {
        ai[nod].second = l[a];
        return;
    }
    int mij = (a + b) >> 1;
    init(nod * 2, a, mij);
    init(nod * 2 + 1, mij + 1, b);
    ai[nod] = Merge(ai[nod * 2], ai[nod * 2 + 1]);
}
void propag(int nod)
{
    if(lazy[nod] == 0)
    {
        return;
    }
    ai[nod * 2].first += lazy[nod];
    ai[nod * 2 + 1].first += lazy[nod];
    lazy[nod * 2] += lazy[nod];
    lazy[nod * 2 + 1] += lazy[nod];
    lazy[nod] = 0;
}
void update(int ua, int ub, int val, int nod, int a, int b)
{
    if(ua <= a && ub >= b)
    {
        ai[nod].first += val;
        lazy[nod] += val;
        return;
    }
    propag(nod);
    int mij = (a + b) >> 1;
    if(ua <= mij)
    {
        update(ua, ub, val, nod * 2, a, mij);
    }
    if(ub > mij)
    {
        update(ua, ub, val, nod * 2 + 1, mij + 1, b);
    }
    ai[nod] = Merge(ai[nod * 2], ai[nod * 2 + 1]);
}
pair<int,int> query(int qa, int qb, int nod, int a, int b)
{
    if(qa <= a && qb >=b)
    {
        return ai[nod];
    }
    propag(nod);
    int mij = (a + b) >> 1;
    if(qa <= mij && qb > mij)
    {
        return Merge(query(qa, qb, nod*2, a, mij), query(qa, qb, nod*2+1, mij+1, b));
    }
    if(qa <= mij)
    {
        return query(qa, qb, nod*2, a, mij);
    }
    return query(qa, qb, nod*2+1, mij+1, b);
}
bool subtask2()
{
#ifdef home
    return false;
#endif // home
    return (n <= 5000 && q <= 5000);
}
bool subtask3()
{
    for(int i=1; i<n; i++)
    {
        if(e[i].x != 1 && e[i].y != 1)
        {
            return false;
        }
    }
    return true;
}
int dfs(int nod, int dad = 0)
{
    l[nod] = 0;
    vector<int> lst;
    int rez = 0;
    for(auto it : G[nod])
    {
        if(it.first == dad)
        {
            continue;
        }
        rez = max(rez, dfs(it.first, nod));
        lst.push_back(l[it.first] + e[it.second].c);
        l[nod] = max(l[nod], l[it.first] + e[it.second].c);
    }
    sort(lst.begin(), lst.end(), greater<int>());
    if(lst.size() == 0)
    {
        return rez;
    }
    if(lst.size() == 1)
    {
        rez = max(rez, lst.front());
        return rez;
    }
    rez = max(rez, lst[0] + lst[1]);
    return rez;
}
void solve2()
{
    int last = 0;
    for(int i=1; i<=q; i++)
    {
        int edge, val;
        cin>>edge>>val;
        edge = (edge + last) % (n - 1) + 1;
        val = (val + last) % w;
        e[edge].c = val;
        last = dfs(1);
        cout<<last<<'\n';
    }
}
void solve3()
{
    int last = 0;
    multiset<int, greater<int>> s;
    for(int i=1; i<n; i++)
    {
        s.insert(e[i].c);
    }
    for(int i=1; i<=q; i++)
    {
        int edge, val;
        cin>>edge>>val;
        edge = (edge + last) % (n - 1) + 1;
        val = (val + last) % w;
        auto it = s.lower_bound(e[edge].c);
        s.erase(it);
        s.insert(val);
        e[edge].c = val;
        last = 0;
        it = s.begin();
        last += *it;
        ++it;
        last += *it;
        cout<<last<<'\n';
    }
}
int cnt = 0;
void euler(int nod, int dad = 0, int root = 0)
{
    p[nod] = (++cnt);
    l[cnt] = nod;
    t[nod] = dad;
    r[nod] = root;
    for(auto it : G[nod])
    {
        if(it.first == dad)
        {
            continue;
        }
        if(dad == 0)
        {
            euler(it.first, nod, it.first);
        }
        else
        {
            euler(it.first, nod, root);
        }
    }
    u[nod] = cnt;
}
void solve5()
{
    euler(1);
    init(1, 1, n);
    for(int i=1; i<n; i++)
    {
        if(e[i].y == t[e[i].x])
        {
            swap(e[i].x, e[i].y);
        }
        update(p[e[i].y], u[e[i].y], e[i].c, 1, 1, n);
    }
    int last = 0;
    for(int i=1; i<=q; i++)
    {
        int edge, val;
        cin>>edge>>val;
        edge = (edge + last) % (n - 1) + 1;
        val = (val + last) % w;
        update(p[e[edge].y], u[e[edge].y], val - e[edge].c, 1, 1, n);
        e[edge].c = val;
        pair<int,int> Max1 = ai[1];
        pair<int,int> Max2 = {0, 0};
        if(p[r[Max1.second]] != 2)
        {
            Max2 = Merge(Max2, query(2, p[r[Max1.second]] - 1, 1, 1, n));
        }
        if(u[r[Max1.second]] != n)
        {
            Max2 = Merge(Max2, query(u[r[Max1.second]] + 1, n, 1, 1, n));
        }
        last = Max1.first + Max2.first;
        cout<<last<<'\n';
    }
}
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
#ifdef home
    freopen("nr.in","r",stdin);
    freopen("nr.out","w",stdout);
#endif // home
    cin>>n>>q>>w;
    for(int i=1; i<n; i++)
    {
        cin>>e[i].x>>e[i].y>>e[i].c;
        G[e[i].x].push_back({e[i].y, i});
        G[e[i].y].push_back({e[i].x, i});
    }
    if(subtask2())
    {
        solve2();
        return 0;
    }
    if(subtask3())
    {
        solve3();
        return 0;
    }
    solve5();
    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... |