树剖+分块 WA#7#8 求条
查看原帖
树剖+分块 WA#7#8 求条
994729
Epitome楼主2024/10/6 10:37
#include <iostream>

#include <vector>

#include <climits>

#define Min INT_MIN >> 1

#define endl '\n'

using namespace std;

const int N = 3e4 + 5, B = 180;

struct Node{
  int dep, siz, fat, top, hvy;
}t[N];

struct Block{
  int sum, Max = Min, bn, ed;
}info[B];

int n, q, dfs[N], a[N], c[N], sum, bid[N];

vector<int>g[N];

void s1(int x, int fa){
  t[x].dep = t[fa].dep + 1;
  t[x].fat = fa, t[x].siz = 1;
  int mx = 0;
  for(int to : g[x]){
    if(to == fa) continue;
    s1(to, x);
    if(mx < t[to].siz){
      mx = t[to].siz;
      t[x].hvy = to;
    }
    t[x].siz += t[to].siz;
  }
}

void s2(int x, int fa, int topx){
  dfs[x] = ++sum, t[x].top = topx;
  if(t[x].hvy != 0) s2(t[x].hvy, x, topx);
  for(int to : g[x]){
    if(to == fa || to == t[x].hvy) continue;
    s2(to, x, to);
  }
}

void renew(int id){
  int s = 0, mx = Min;
  for(int i = info[id].bn; i <= info[id].ed; ++i)
    s += a[i], mx = max(mx, a[i]);
  info[id].sum = s, info[id].Max = mx;
}

void update(int x, int w){
  a[x] = w;
  renew(bid[x]);
}

int query_sum(int l, int r){
  int ret = 0;
  if(bid[l] == bid[r]){
    for(int i = l; i <= r; ++i) ret += a[i];
  }else{
    int i = l, j = r;
    while(bid[i] == bid[l]){
      ret += a[i], ++i;
    }
    while(bid[j] == bid[r]){
      ret += a[j], --j;
    }
    for(int p = bid[i]; p <= bid[j]; ++p){
      ret += info[p].sum;
    }
  }
  return ret;
}

int query_max(int l, int r){
  int ret = Min;
  if(bid[l] == bid[r]){
    for(int i = l; i <= r; ++i) ret = max(ret, a[i]);
  }else{
    int i = l, j = r;
    while(bid[i] == bid[l]){
      ret = max(ret, a[i]), ++i;
    }
    while(bid[j] == bid[r]){
      ret = max(ret, a[j]), --j;
    }
    for(int p = bid[i]; p <= bid[j]; ++p){
      ret = max(ret, info[p].Max);
    }
  }
  return ret;
}

int solve_sum(int x, int y){
  int ret = 0;
  while(t[x].top != t[y].top){
    bool flag = t[t[x].top].dep >= t[t[y].top].dep;
    if(flag == 1){
      ret += query_sum(dfs[t[x].top], dfs[x]);
      x = t[t[x].top].fat;
    }else{
      ret += query_sum(dfs[t[y].top], dfs[y]);
      y = t[t[y].top].fat;
    }
  }
  if(t[x].dep > t[y].dep) swap(x, y);
  return ret + query_sum(dfs[x], dfs[y]);
}

int solve_max(int x, int y){
  int ret = Min;
  while(t[x].top != t[y].top){
    bool flag = t[t[x].top].dep >= t[t[y].top].dep;
    if(flag == 1){
      ret = max(ret, query_max(dfs[t[x].top], dfs[x]));
      x = t[t[x].top].fat;
    }else{
      ret = max(ret, query_max(dfs[t[y].top], dfs[y]));
      y = t[t[y].top].fat;
    }
  }
  if(t[x].dep > t[y].dep) swap(x, y);
  return max(ret, query_max(dfs[x], dfs[y]));
}

int main(){
  ios :: sync_with_stdio(0), cin.tie(0);
  cin >> n;
  for(int i = 1, x, y; i < n; ++i){
    cin >> x >> y;
    g[x].push_back(y), g[y].push_back(x);
  }
  s1(1, 0), s2(1, 0, 1);
  for(int i = 1; i <= n; cin >> a[i++]);
  for(int i = 1; i <= n; ++i){
    c[dfs[i]] = a[i];
    bid[i] = i / B;
    info[bid[i]].sum += a[i];
    info[bid[i]].Max = max(info[bid[i]].Max, a[i]);
  }
  for(int i = 1; i <= n; ++i) a[i] = c[i];
  for(int i = 0; i < B; ++i)
    info[i].bn = i * B, info[i].ed = (i + 1) * B - 1;
  cin >> q;
  while(q--){
    string op;
    int u, v;
    cin >> op >> u >> v;
    if(op == "CHANGE"){
      update(dfs[u], v);
    }else if(op == "QMAX"){
      cout << solve_max(u, v) << endl;
    }else{
      cout << solve_sum(u, v) << endl;
    }
  }
  return 0;
}

2024/10/6 10:37
加载中...