이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
// ~~ Be name khoda ~~ //
 
#include <bits/stdc++.h>
 
using namespace std;
 
typedef long long ll;
 
#define all(x)    x.begin(), x.end()
#define fi        first
#define se        second
#define pb        push_back
 
const int maxn5 = 1e5 + 10;
const int maxnt = 4e5 + 10;
const ll  inf   = 2e18;
 
 
struct segment_tree{
 
    ll val[maxn5], lazy[maxnt];
    pair <ll, int> mx[maxnt];
 
    inline void build(int l, int r, int v){
        if(r - l == 1){
            mx[v] = {val[l], l};
            return;
        }
        int mid = (l + r) >> 1;
        build(l, mid, v * 2);
        build(mid, r, v * 2 + 1);
        mx[v] = max(mx[v * 2], mx[v * 2 + 1]);
    }
 
    inline void add(int l, int r, int lq, int rq, ll valu, int v){
        if(rq <= l || r <= lq)
            return;
        if(lq <= l && r <= rq){
            lazy[v] += valu;
            mx[v].fi += valu;
            return;
        }
        int mid = (l + r) >> 1;
        add(l, mid, lq, rq, valu, v * 2);
        add(mid, r, lq, rq, valu, v * 2 + 1);
        mx[v] = max(mx[v * 2], mx[v * 2 + 1]);
        mx[v].fi += lazy[v];
    }
 
    inline void update(int l, int r, int id, ll valu, int v){
        if(r - l == 1){
            lazy[v] = 0;
            val[l] = valu;
            mx[v] = {valu, l};
            return;
        }
        int mid = (l + r) >> 1;
        if(id < mid)
            update(l, mid, id, valu - lazy[v], v * 2);
        else
            update(mid, r, id, valu - lazy[v], v * 2 + 1);
        mx[v] = max(mx[v * 2], mx[v * 2 + 1]);
        mx[v].fi += lazy[v];
    }
 
    inline pair<ll, int> get_max(int l, int r, int lq, int rq, int v){
        if(rq <= l || r <= lq)
            return {-inf, 0};
        if(lq <= l && r <= rq)
            return mx[v];
        int mid = (l + r) >> 1;
        auto ans = max(get_max(l, mid, lq, rq, v * 2), get_max(mid, r, lq, rq, v * 2 + 1));
        return {ans.fi + lazy[v], ans.se};
    }
 
 
} fut_seg, hld_seg;
 
int ti = -1, st[maxn5], ft[maxn5], pos = -1, n;
int id[maxn5], big[maxn5], sz[maxn5], top[maxn5], ver[maxn5];
int h[maxn5], f[maxn5], a[maxn5], b[maxn5], retuid[maxn5];
ll hw[maxn5], mxw[maxn5], paredge[maxn5], c[maxn5];
vector <pair<int, ll>> adj[maxn5];
 
inline void dfs_det(int v, int par){
    sz[v] = 1;
    big[v] = -1;
    st[v] = ++ti;
    ver[ti] = v;
    mxw[v] = 0;
    for(auto [u, c] : adj[v]) if(u != par){
        h[u] = h[v] + 1;
        hw[u] = hw[v] + c;
        paredge[u] = c;
        dfs_det(u, v);
        sz[v] += sz[u];
        mxw[v] = max(mxw[v], mxw[u] + c);
        if(big[v] == -1 || sz[big[v]] <= sz[u])
            big[v] = u;
    }
    ft[v] = ti;
    return;
}
 
inline void dfs_hld(int v, int par){
    id[v] = ++pos;
    if(big[v] != -1){
        top[big[v]] = top[v];
        f[big[v]] = f[v];
        dfs_hld(big[v], v);
    }
    ll val = 0;
    for(auto [u, c] : adj[v]) if(u != big[v] && u != par){
        f[u] = v;
        top[u] = u;
        val = max(val, (mxw[u] + c));
        dfs_hld(u, v);
    }
    hld_seg.val[id[v]] = val - hw[v];
    retuid[v] = pos;
    return;
}
 
inline void update(int v, int u){
    if(v == -1)
        return;
    if(u != big[v]){
        ll val = fut_seg.get_max(0, n, st[v], st[big[v]], 1).fi;
        val = max(val, fut_seg.get_max(0, n, ft[big[v]] + 1, ft[v] + 1, 1).fi);
        hld_seg.update(0, n, id[v], val - 2 * fut_seg.get_max(0, n, st[v], st[v] + 1, 1).fi, 1);
    }
    update(f[v], top[v]);
}
 
inline ll get(int v){
    auto tmp = hld_seg.get_max(0, n, id[top[v]], id[v], 1);
    ll res = tmp.fi;
    if(f[v] == -1)
        return res;
    res = max(res, get(f[v]));
    int u = top[v];
    int z = f[v];
    ll ezafe = fut_seg.get_max(0, n, st[z], st[z] + 1, 1).fi;
    ezafe *= 2;
    res = max(res, fut_seg.get_max(0, n, st[z], st[u], 1).fi - ezafe);
    res = max(res, fut_seg.get_max(0, n, ft[u] + 1, ft[z] + 1, 1).fi - ezafe);
    return res;
}
 
 
int main(){
    ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
 
    ll w;
    int q; cin >> n >> q >> w;
 
    for(int i = 0; i < n - 1; i++){
        cin >> a[i] >> b[i] >> c[i];
        a[i]--; b[i]--;
        adj[a[i]].pb({b[i], c[i]});
        adj[b[i]].pb({a[i], c[i]});
    }
 
    f[0] = -1;
    top[0] = 0;
    dfs_det(0, -1);
    dfs_hld(0, -1);
    for(int i = 0; i < n; i++)
        fut_seg.val[st[i]] = hw[i];
    fut_seg.build(0, n, 1);
    hld_seg.build(0, n, 1);
 
    ll last = 0;
    for(int i = 0; i < q; i++){
        ll d, e; cin >> d >> e;
        d = (d + last) % (n - 1);
        e = (e + last) % w;
        if(st[a[d]] > st[b[d]])
            swap(a[d], b[d]);
        fut_seg.add(0, n, st[b[d]], ft[b[d]] + 1, e - c[d], 1);
        update(a[d], b[d]);
        hld_seg.add(0, n, id[b[d]], retuid[b[d]] + 1, -e + c[d], 1);
        auto tmp = fut_seg.mx[1];
        int v = ver[tmp.se];
        last = tmp.fi + get(v);
        last = max(last, tmp.fi);
        c[d] = e;
        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... |