P6845 [CEOI 2019] Dynamic Diameter

考虑直径定义:

\[\max_{x\leq y}(d_x+d_y-d_{\mathrm{lca}(x,y)}) \]

我们发现问题难点在于维护 \(d_{\mathrm{lca}(x,y)}\)。我们考虑欧拉序求 \(\mathrm{lca}\) 的方法,即:

\[d_{\mathrm{lca}(x,y)}=\min_{\mathrm{any}_x\leq z\leq \mathrm{any}_y}(d_{e_z}) \]

那么我们发现原式可以转化成:

\[\max_{x\leq y}^{2n-1}(a_x+a_y-2\min_{x\leq z\leq y}(a_z)) \]

其中 \(a_i=d_{e_i}\)。那么我们考虑线段树维护这个东西,对于边修改则就相当于是对于一个子树的 \(\mathrm{dep}\leftarrow \mathrm{dep}+v\)。区间加即可。

#include <bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
using namespace std;
typedef long long ll;
const int MAXN=2e5+5;
struct Edge{
    int u,v;
    ll w;
}e[MAXN];
vector<pair<int,int>>adj[MAXN];
ll dep[MAXN];
int olx[MAXN],fs[MAXN],ed[MAXN],tot;
void dfs(int u,int f){
    olx[++tot]=u;
    fs[u]=ed[u]=tot;
    for(auto eg:adj[u]){
        if(eg.first==f){continue;}
        if(u!=e[eg.second].u){
            swap(e[eg.second].u,e[eg.second].v);
        }
        dep[eg.first]=dep[u]+e[eg.second].w;
        dfs(eg.first,u);
        olx[++tot]=u;
        ed[u]=tot;
    }
}
struct node{
    ll ans,lv,rv,ma,mn,tg;
    void tt(ll v){
        tg+=v;
        lv-=v;
        rv-=v;
        ma+=v;
        mn+=v;
    }
    #define lc(u) (u<<1)
    #define rc(u) (u<<1|1)
}t[MAXN*4];
void push_up(int u){
    t[u].ans=max({
                t[lc(u)].ans,t[rc(u)].ans,
                t[lc(u)].lv+t[rc(u)].ma,
                t[lc(u)].ma+t[rc(u)].rv
                });
    t[u].lv=max({t[lc(u)].lv,t[rc(u)].lv,
                t[lc(u)].ma-2*t[rc(u)].mn});
    t[u].rv=max({t[lc(u)].rv,t[rc(u)].rv,
                t[rc(u)].ma-2*t[lc(u)].mn});
    t[u].ma=max(t[lc(u)].ma,t[rc(u)].ma);
    t[u].mn=min(t[lc(u)].mn,t[rc(u)].mn);
}
void push_down(int u){
    t[lc(u)].tt(t[u].tg);
    t[rc(u)].tt(t[u].tg);
    t[u].tg=0;
}
void build(int u,int l,int r){
    if(l==r){
        t[u].ans=0;
        t[u].lv=t[u].rv=-dep[olx[l]];
        t[u].ma=t[u].mn=dep[olx[l]];
        return;
    }
    int mid=(l+r)>>1;
    build(lc(u),l,mid);
    build(rc(u),mid+1,r);
    push_up(u);
}
void modify(int u,int l,int r,int ql,int qr,ll v){
    if(ql<=l&&r<=qr){
        t[u].tt(v);
        return;
    }
    push_down(u);
    int mid=(l+r)>>1;
    if(ql<=mid){
        modify(lc(u),l,mid,ql,qr,v);
    }
    if(mid+1<=qr){
        modify(rc(u),mid+1,r,ql,qr,v);
    }
    push_up(u);
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int n,q;ll W;
    cin>>n>>q>>W;
    rep(i,1,n-1){
        cin>>e[i].u>>e[i].v>>e[i].w;
        adj[e[i].u].push_back({e[i].v,i});
        adj[e[i].v].push_back({e[i].u,i});
    }
    dfs(1,0);
    build(1,1,tot);
    ll la=0;
    rep(i,1,q){
        ll d;ll E;
        cin>>d>>E;
        d=(d+la)%(n-1)+1;
        E=(E+la)%W;
        modify(1,1,tot,fs[e[d].v],ed[e[d].v],E-e[d].w);
        e[d].w=E;
        la=t[1].ans;
        cout<<t[1].ans<<"\n";
    }
    return 0;
}
posted @ 2026-02-27 11:13  tanghg  阅读(12)  评论(0)    收藏  举报