求助线段树合并
查看原帖
求助线段树合并
530349
天空即为极限楼主2023/1/14 07:27
#include <bits/stdc++.h>
using namespace std;

const int N = 1e5 + 5;

struct node {
  int l, r, val;
}t[N << 6];
int f[N][21], dep[N], tot, root[N];
vector <int> v[1000005];
void Init (int x, int fa) {
  f[x][0] = fa; dep[x] = dep[fa] + 1;
  for (int i = 1; i <= 20; i ++)
    f[x][i] = f[f[x][i - 1]][i - 1];
  for (auto i : v[x]) {
    if (i == fa) continue;
    Init (i, x);
  }
}

int LCA (int x, int y) {
  if (dep[x] < dep[y]) swap (x, y);
  for (int i = 20; i >= 0; i --)
    if (dep[f[x][i]] >= dep[y]) x = f[x][i];
  if (x == y) return x;
  for (int i = 20; i >= 0; i --)
    if (f[x][i] != f[y][i]) 
      x = f[x][i], y = f[y][i];
  return f[x][0];
}

void pushup (int cur) {
  t[cur].val = 0;
  if (t[cur].l) t[cur].val = t[t[cur].l].val;
  if (t[cur].r) t[cur].val = max (t[cur].val, t[t[cur].r].val);
}

void insert (int &cur, int l, int r, int x, int val) {
  if (!cur) cur = ++ tot;
  if (l == r) return t[cur].val += val, void ();
  int mid = l + r >> 1;
  if (x <= mid) insert (t[cur].l, l, mid, x, val);
  else insert (t[cur].r, mid + 1, r, x, val);
  pushup (cur);
}

void merge (int &cur, int cur2, int l, int r) {
  if (!cur or !cur2) return cur = cur + cur2, void ();
  if (l == r) return t[cur].val += t[cur2].val, void ();
  int mid = l + r >> 1;
  merge (t[cur].l, t[cur2].l, l, mid);
  merge (t[cur].r, t[cur2].r, mid + 1, r);
  pushup (cur);
}

int ask (int cur, int l, int r) {
  if (!cur or t[cur].val == 0) return 0;
  if (l == r) return l;
  int mid = l + r >> 1;
  if (t[t[cur].l].val == t[cur].val) return ask (t[cur].l, l, mid);
  else return ask (t[cur].r, mid + 1, r);
}

void dfs (int x, int fa) {
  for (auto i : v[x]) {
    if (i == fa) continue;
    dfs (i, x);
    merge (root[x], root[i], 1, N);
  }
}

void OutPut (int cur, int l, int r) {
  if (!cur or l == r) return;
  int mid = l + r >> 1;
  cout << cur << " val: " << t[cur].val << " Lson: " << t[cur].l << " Rson: " << t[cur].r << " L: " << l << " R: " << r << "\n";
  OutPut (t[cur].l, l, mid);
  OutPut (t[cur].r, mid + 1, r);
}

int main () {
  int n, m; cin >> n >> m;
  for (int i = 1; i <= n - 1; i ++) {
    int x, y; cin >> x >> y;
    v[x].emplace_back (y);
    v[y].emplace_back (x);
  }
  Init(1, 0);
  while (m --) {
    int x, y, z, lca; cin >> x >> y >> z;
    lca = LCA(x, y);
    insert (root[x], 1, N, z, 1);
    insert (root[y], 1, N, z, 1);
    insert (root[lca], 1, N, z, -1);
    insert (root[f[lca][0]], 1, N, z, -1);
   // cout << f[lca][0] << "\n";
  }
   
  dfs (1, 0); //OutPut (root[1], 1, N);
  for (int i = 1; i <= n; i ++) {
    cout << ask (root[i], 1, N) << "\n";
  }
}
/*

*/

15pts

2023/1/14 07:27
加载中...