제출 #1350758

#제출 시각아이디문제언어결과실행 시간메모리
1350758bakhtiyarnDynamic Diameter (CEOI19_diameter)C++20
42 / 100
5095 ms26048 KiB
#include <bits/stdc++.h>
using namespace std;
#define int long long

const int N = 3e5+5;
vector<array<int, 2>> g[N];
int in[N], sub[N];
int C = 1;
int dis[N], idx[N];
int best[N], par[N], deep[N];

void dfs(int u, int p, int IDX){
  par[u] = p;
  idx[u] = IDX;
  
  in[u] = C++;
  
  sub[u] = 1; int ptr = -1;
  for(auto [to, w]: g[u]){
    ptr++;
    if(to == p) continue;
    
    deep[to] = deep[u]+1;
    dis[to] = dis[u] + w;
    if(u == 1) dfs(to, u, ptr);
    else dfs(to, u, IDX);
    
    sub[u] += sub[to];
  }
}

struct Segtree {
  vector<int> sg, lz;
  void fill(int n) { sg.assign(n*4, 0); lz.assign(n*4, 0); }
  
  void push(int u, int l, int r){
    sg[u] += lz[u];
    
    if(l != r){
      lz[u*2] += lz[u];
      lz[u*2+1] += lz[u];
    }
    lz[u] = 0;
  }
  
  void update(int u, int l, int r, int x, int y, int v){
    push(u, l, r);
    if(y < l or x > r) return;
    if(x <= l and y >= r) {
      lz[u] += v;
      push(u, l, r);
      return;
    }
    
    int m = (l+r)/2;
    update(u*2, l, m, x, y, v);
    update(u*2+1, m+1, r, x, y, v);
    sg[u] = max(sg[u*2], sg[u*2+1]);
  }
  
  int get(int u, int l, int r, int x, int y){
    push(u, l, r);
    if(y < l or x > r) return 0;
    if(x <= l and y >= r) return sg[u];
    
    int m = (l+r)/2;
    auto a1 = get(u*2, l, m, x, y);
    auto a2 = get(u*2+1, m+1, r, x, y);
    return max(a1, a2);
  }
};

multiset<array<int, 2>> V;

void upd(int x, int u){
  if(!x) return;
  
  if(best[u]) {
    auto it = V.find({best[u], u});
    V.erase(it);
    
    V.insert({x, u});
    best[u] = x;
    return;
  }
  best[u] = x;
  V.insert({x, u});
}


Segtree sg;
int n, q, W; 

int BEST(int u){
  vector<int> v = {0, 0};
  int kp = sg.get(1, 1, n, in[u], in[u]);
  
  for(auto [to, w]: g[u]){
    if(to == par[u]) continue;
    v.push_back(sg.get(1, 1, n, in[to], in[to]+sub[to]-1) - kp);
  }
  
  sort(v.rbegin(), v.rend());
  return v[0]+v[1];
}

// for(int i=1; i<=n; i++) 
void solve(){
  cin >> n >> q >> W;
  vector<array<int, 3>> input;
  for(int i=1; i<n; i++) {
    int x, y, w; cin >> x >> y >> w;
    input.push_back({x, y, w});
    g[x].push_back({y, w});
    g[y].push_back({x, w});
  }
  dfs(1, 0, 0);
  
  
  sg.fill(n);
  
  for(int i=1; i<=n; i++) {
    sg.update(1, 1, n, in[i], in[i], dis[i]);
  }
  
  V = {{0, 0}, {0, 0}};
  
  for(int i=1; i<=n; i++){
    upd(BEST(i), i);
  }
  
  int last = 0;
  while(q--){
    int d, aft; cin >> d >> aft;
    d = (d+last)%(n-1);
    aft = (aft+last)%W;
    
    auto [u, v, bef] = input[d];
    if(deep[u] > deep[v]) swap(u, v);
    sg.update(1, 1, n, in[v], in[v]+sub[v]-1, aft-bef);
    input[d][2] = aft;
    
      // cout << u << ": " << BEST(v) << endl;
    while(v){
      upd(BEST(v), v);
      v = par[v];
    }
    // cout << aft-bef << endl;
    auto it = --V.end();
    last = (*it)[0];
    cout << last << '\n';
    // cout << ans[0] << '\n';
  }
}

signed main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  solve();
}
#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...