Submission #1361846

#TimeUsernameProblemLanguageResultExecution timeMemory
1361846piolkDynamic Diameter (CEOI19_diameter)C++20
100 / 100
156 ms45460 KiB
#include <bits/stdc++.h>
using namespace std;

struct nd{
    //ai-aj+ak
    long long mi,mj,mij,mjk,ans,lz;
    inline void add(long long d){
        mi+=d;
        mj-=2*d;
        mij-=d;
        mjk-=d;
        lz+=d;
    }
    inline nd operator+(nd &other){
        return {
            max(mi,other.mi),
            max(mj,other.mj),
            max({mij,other.mij,mi+other.mj}),
            max({mjk,other.mjk,mj+other.mi}),
            max({ans,other.ans,mi+other.mjk,mij+other.mi})
        };
    }
};

constexpr int maxn=1e5 + 5;
vector<pair<int,long long>> t[maxn];
int fir[maxn],las[maxn];
long long we[maxn],dep[maxn];

nd tree[8*maxn];
int len=1;

vector<long long> tour;
int tim=-1;
void dfs(int v,int p,long long d){
    dep[v]=d;
    fir[v]=++tim;
    tour.push_back(d);
    for (auto &[u,w]:t[v]){
        if (u==p) continue;
        dfs(u,v,d+w);
        tim++;
        tour.push_back(d);
    }
    las[v]=tim;
}

void push(int v){
    tree[2*v].add(tree[v].lz);
    tree[2*v+1].add(tree[v].lz);
    tree[v].lz=0;
}

void radd(int v,int cs,int ce,int ls,int le,long long w){
    if (cs>=ls && ce<=le){
        tree[v].add(w);
        return;
    }
    if (cs>le || ce<ls) return;
    int mid=(cs+ce)/2;
    push(v);
    radd(2*v,cs,mid,ls,le,w);radd(2*v+1,mid+1,ce,ls,le,w);
    tree[v]=tree[2*v]+tree[2*v+1];
}

int main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0);

    long long n,q,w;
    cin>>n>>q>>w;

    vector<pair<int,int>> edg(n-1);
    for (int i=0;i<n-1;i++){
        long long a,b,c;
        cin>>a>>b>>c;
        t[a].push_back({b,c});
        t[b].push_back({a,c});
        edg[i]={a,b};
        we[i]=c;
    }

    dfs(1,0,0);
    while (len<tour.size()) len<<=1;

    for (int i=0;i<tour.size();i++) tree[i+len].add(tour[i]);
    for (int i=len-1;i>=1;i--) tree[i]=tree[2*i]+tree[2*i+1];

    long long last=0;

    while (q--){
        long long d,e;
        cin>>d>>e;
        d=(d+last)%(n-1);
        e=(e+last)%w;
        auto [e1,e2]=edg[d];
        if (dep[e1]<dep[e2]) swap(e1,e2);
        radd(1,0,len-1,fir[e1],las[e1],e-we[d]);
        we[d]=e;
        last=tree[1].ans;
        cout<<last<<"\n";
    }

    return 0;
}
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...