Submission #1365771

#TimeUsernameProblemLanguageResultExecution timeMemory
1365771mohammadsamDynamic Diameter (CEOI19_diameter)C++17
100 / 100
2264 ms251028 KiB
/*
    in the name of god
*/
//#pragma GCC optimize("Ofast,O3,unroll-loops")
//#pragma GCC target("avx,avx2,fma")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4.1,sse4.2,sse4a,avx,avx2,popcnt,tune=native")

#include <bits/stdc++.h>

using namespace std;
#define int long long 
typedef pair<int,int> pii;
typedef pair<long long ,long long> pll;
typedef long long ll ;

#define File          freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
#define all(V)        V.begin(),V.end()
#define setprec(x)    fixed << setprecision(x)
#define Mp(a,b)       make_pair(a,b)
#define len(V)        (int)(V.size())
#define sep           ' '
#define endl          '\n'
#define pb            push_back
#define fi            first
#define sec           second
#define popcount(x)   __builtin_popcount(x)
#define lid           u<<1
#define rid           (lid)|1
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());

const ll N = 1e5 + 10,SQ=320,LOG=22;
const ll inf = 2e18 + 10 , MD = 1e9 + 7;

inline ll md(ll x){ x %= MD; return (x < 0 ? x + MD : x);}
int n,q;
vector<pii> g[N];
int sz[N];
bool mark[N];

int dfs_sz(int u,int p){
    sz[u] = 1;
    for(auto h : g[u]){
        if(h.fi != p  && !mark[h.fi]) sz[u] += dfs_sz(h.fi,u);
    }
    return sz[u];
}
int centroid(int u,int p,int S){
    for(auto h : g[u]){
        if(h.fi != p && !mark[h.fi] && 2*sz[h.fi] > S) return centroid(h.fi,u,S);
    }
    return u;
}
int st[N][LOG],ft[N][LOG];
int who[N][LOG];
int who2[N][LOG];
vector<int> vec[N];
int tim=0;
void DFS(int u,int p,int root,int l,int W=0){
    vec[root].pb(u);
    who[u][l] = root;
    who2[u][l] = W;
    st[u][l] = tim++;
    for(auto h : g[u]){
        if(h.fi != p && !mark[h.fi]){
            DFS(h.fi,u,root,l,(u == root ? h.fi : W));
        }
    }
    ft[u][l] = tim;
}
int lev[N];
struct node{
    pii mx;
    int lazy;
    node*lc,*rc;
    node(pii mx): mx(mx),lazy(0LL),lc(NULL),rc(NULL){}
    node(){}
};
node* root[N];
void fix(node*& u){
    u->mx = {-inf,-inf};
    if(u->lc) u->mx = max(u->mx,u->lc->mx);
    if(u->rc) u->mx = max(u->mx,u->rc->mx);
}
void build(int id,node*& u,int l,int r){
    if(r-l==1){
        u = new node({0,vec[id][l]});
        return;
    }
    u = new node({-inf,-inf});
    int mid = (l+r)>>1;
    build(id,u->lc,l,mid);
    build(id,u->rc,mid,r);
    fix(u);
}
void shift(node*& u,int v){
    u->mx.fi += v;
    u->lazy += v;
}
void relax(node*& u){
    shift(u->lc,u->lazy);
    shift(u->rc,u->lazy);
    u->lazy= 0;
}

void update(int s,int e,int v,node*& u,int l,int r){
    if(e <= s || e <= l || r <= s) return;
    if(s <= l  && r <= e){
        shift(u,v);
        return;
    }
    int mid = (l+r)>>1;
    relax(u);
    update(s,e,v,u->lc,l,mid);
    update(s,e,v,u->rc,mid,r);
    fix(u);
}
pii get(int s,int e,node*& u,int l,int r){
    if(e <= s) return {-inf,-inf};
    if(s <= l && r <= e) return u->mx;
    int mid = (l+r)>>1;
    relax(u);
    if(e <= mid) return get(s,e,u->lc,l,mid);
    if(s >= mid) return get(s,e,u->rc,mid,r);
    return max(get(s,e,u->lc,l,mid),get(s,e,u->rc,mid,r));
}
void dec(int u,int l=0){
    int c = centroid(u,u,dfs_sz(u,u));
    mark[c] = 1;
    tim = 0;
    DFS(c,c,c,l);
    lev[c] = l;
    build(c,root[c],0,len(vec[c]));
    for(auto h : g[c]){
        if(!mark[h.fi]) dec(h.fi,l+1);
    }
}
void Upd(int u,int v,int x){
    int l = min(lev[u],lev[v]);
    while(l >= 0){
        if(st[u][l] > st[v][l]) swap(u,v);
        update(st[v][l],ft[v][l],x,root[who[v][l]],0,len(vec[who[v][l]]));
        l--;
    }
}
pii ask(int u){
    int l = lev[u];
    pii ans = {0,u};
    ans = max(ans,get(0,len(vec[u]),root[u],0,len(vec[u])));
    l--;
    int lst;
    while(l >= 0){
        int v = who[u][l];
        lst = who2[u][l];
        pii tmp = get(0,st[lst][l],root[v],0,len(vec[v]));
        tmp = max(tmp,get(ft[lst][l],len(vec[v]),root[v],0,len(vec[v])));
        tmp.fi += get(st[u][l],st[u][l]+1,root[v],0,len(vec[v])).fi;
        ans = max(ans,tmp);
        l--;
    }
    return ans;
}
void print(node*& u,int l,int r){
    if(r-l==1){
        cout << (u->mx.fi) << sep;
        return;
    }
    relax(u);
    int mid = (l+r)>>1;
    print(u->lc,l,mid);
    print(u->rc,mid,r);
    fix(u);
}
int w;
pair<pii,int> E[N];
pii dfs(int u,int p){
    pii ans = {0,u};
    for(auto h : g[u]){
        if(h.fi != p){
            pii p = dfs(h.fi,u);
            p.fi += h.sec;
            ans = max(ans,p);
        }
    }
    return ans;
}
int32_t main() {
    ios_base::sync_with_stdio(false);cout.tie(0);cin.tie(0);
    cin >> n >> q >> w;
    for(int i = 0; i < n -1;i++){
        int u,v,w;
        cin >> u >> v >> w;
        g[u].pb({v,w});
        g[v].pb({u,w});
        E[i] = {{u,v},w};
    }
    dec(1,0);
    for(int i = 0 ;i < n - 1;i++){
        Upd(E[i].fi.fi,E[i].fi.sec,E[i].sec);
    }
    int lst = 0;
    
    while(q--){
        int d,e;
        cin >> d >> e;
        d = (d+lst)%(n-1);
        e = (e + lst%w)%w;
        
        Upd(E[d].fi.fi,E[d].fi.sec,e - E[d].sec);
        
        E[d].sec = e;
        pii tmp = ask(1);
        tmp = ask(tmp.sec);
        lst = tmp.fi;
        cout << lst << endl;
    }
    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...