Submission #1261253

#TimeUsernameProblemLanguageResultExecution timeMemory
1261253minhpkDynamic Diameter (CEOI19_diameter)C++20
100 / 100
258 ms83356 KiB
#include <bits/stdc++.h>
#define int long long
using namespace std;

const int maxn = 200005;
const int INF  = (int)1e16;

int a,q,sadge;
vector<pair<int,int>> z[maxn];
int high[maxn];
int sta[maxn], fin[maxn], euler[3*maxn], tour=0;
int depth[1000005];
int par[300001][21];
bool cmp(pair<int,int> a,pair<int,int> b){
     return a.second<b.second;
}
void dfs(int u, int p){
    sta[u] = ++tour;
    par[u][0]=p;
    euler[tour] = u;
    for(auto &pr: z[u]){
        int v = pr.first, w = pr.second;
        if(v==p) continue;
        high[v] = high[u] + w;
        depth[v]=depth[u]+1;
        dfs(v, u);
        euler[++tour] = u;
    }
    fin[u] = ++tour;
    euler[tour] = u;
}
int lca1(int x,int y){
    for (int i=20;i>=0;i--){
         if (depth[par[x][i]]>depth[y]){
             x=par[x][i];
         }
    }
    return x;
}
int lca(int x,int y){
    if (depth[x]<depth[y]){
        swap(x,y);
    }
    for (int i=20;i>=0;i--){
         if (depth[par[x][i]]>=depth[y]){
             x=par[x][i];
         }
    }
    if (x==y){
        return x;
    }
    for (int i=20;i>=0;i--){
         if (par[x][i]!=par[y][i] && par[x][i]!=0){
             x=par[x][i];
             y=par[y][i];
         }
    }
    return par[x][0];
}

struct node {
    int max1, min1, lazy;
    int val, val1;
};
node f[12*maxn];


node combine(const node &A, const node &B){
    node R;

    R.max1 = max(A.max1, B.max1);
    R.min1 = min(A.min1, B.min1);
    R.lazy = 0;

    R.val  = max({ A.val, B.val, B.max1 - 2*A.min1 });

    R.val1 = max({ A.val1, B.val1, A.max1 - 2*B.min1 });
    return R;
}

void push(int id){
    if(f[id].lazy){
        int d = f[id].lazy;
        for(int ch: {id*2, id*2+1}){
            f[ch].lazy += d;
            f[ch].max1  += d;
            f[ch].min1  += d;
            f[ch].val   -= d;
            f[ch].val1  -= d;
        }
        f[id].lazy = 0;
    }
}
void build(int id, int l, int r){
    if(l==r){
        int h = high[euler[l]];
        f[id].max1 = f[id].min1 = h;
        f[id].lazy = 0;
        f[id].val  = -INF;
        f[id].val1 = -INF;
        return;
    }
    int m = (l+r)/2;
    build(id*2,   l,   m);
    build(id*2+1, m+1, r);
    f[id] = combine(f[id*2], f[id*2+1]);
}
void update(int id, int l, int r, int x, int y, int d){
    if(y<l || x>r) return;
    if(x<=l && r<=y){
        f[id].max1 += d;
        f[id].min1 += d;
        f[id].lazy += d;
        f[id].val  -= d;
        f[id].val1 -= d;
        return;
    }
    push(id);
    int m = (l+r)/2;
    update(id*2,   l,   m, x, y, d);
    update(id*2+1, m+1, r, x, y, d);
    f[id] = combine(f[id*2], f[id*2+1]);
}

node get(int id, int l, int r, int x, int y){
    if(y<l || x>r){
       return { -INF, INF, 0, -INF, -INF };
    }
    if(x<=l && r<=y){
        return f[id];
    }
    push(id);
    int m = (l+r)/2;
    return combine(
        get(id*2,   l,   m, x, y),
        get(id*2+1, m+1, r, x, y)
    );
}
int get1(int id,int l,int r,int pos){
    if (l==r){
        return f[id].max1;
    }
    int mid=(l+r)/2;
    push(id);
    if (pos<=mid){
        return get1(id*2,l,mid,pos);
    }else{
        return get1(id*2+1,mid+1,r,pos);
    }
}
int get2(int id,int l,int r,int val){
    if (l==r){
        return l;
    }
    int mid=(l+r)/2;
    push(id);
    if (f[id*2].max1==val){
        return get2(id*2,l,mid,val);
    }else{
        return get2(id*2+1,mid+1,r,val);
    }
}
struct node1{
    int x,y,t;
};
node1 edge[1000005];

vector <pair<int,int>> segment;
vector <pair<int,int>> v;
signed main(){
    ios::sync_with_stdio(false);
    cin.tie(NULL);

    cin >> a >> q >> sadge;
    for(int i=1;i<a;i++){
        int x,y,t;
        cin >> x >> y >> t;
        z[x].push_back({y,t});
        z[y].push_back({x,t});
        edge[i]={x,y,t};
    }
    depth[0]=-1;
    dfs(1,0);
    build(1,1,tour);
    for (int i=1;i<a;i++){
         if (depth[edge[i].x]<depth[edge[i].y]){
             swap(edge[i].x,edge[i].y);
         }
    }
    for (int j=1;j<=20;j++){
         for (int i=1;i<=a;i++){
              par[i][j]=par[par[i][j-1]][j-1];
         }
    }
   // cout << tour << "\n";
    
    int cnt=0;
    int last=0;
    while(q--){
        int x,y;
        cin >> x >> y;
        x=(last+x)%(a-1);
        y=(last+y)%sadge;
       // cout << x << " " << y << "\n";
        x++;
        int cur=edge[x].t;
        int diff=y-cur;
        int v=edge[x].x;
        edge[x].t=y;
        update(1,1,tour,sta[v],fin[v],diff);
        int maxlen=f[1].max1;
        int pos=get2(1,1,tour,maxlen);
        int res=get(1,1,tour,1,pos).val1;
        int res1=get(1,1,tour,pos,tour).val;
        cout << max(res,res1)+maxlen << "\n";
        last=max(res,res1)+maxlen;
    }
    return 0;
}
/*
5
1 2 1
1 4 2
2 3 3
2 5 4
2

2 1 100
1 2 4 1 3 4 5

*/
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...