# BZOJ3307 雨天的尾巴

## Code

#include <bits/stdc++.h>

using namespace std;

#define squ(x) ((LL)(x) * (x))
#define debug(...) fprintf(stderr, __VA_ARGS__)

typedef long long LL;
typedef pair<int, int> pii;

inline int read() {
int sum = 0, fg = 1; char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') fg = -1;
for (; isdigit(c); c = getchar()) sum = (sum << 3) + (sum << 1) + (c ^ 0x30);
return fg * sum;
}

const int maxn = 1e5 + 10;

struct node {
int x, y, z;
}op[maxn];

int n, m, len, t[maxn], rt[maxn], ans[maxn];

namespace ST {

int cnt;
struct node {
int ls, rs;
}A[maxn << 6];
pii v[maxn << 6];

void push_up(int rt) { v[rt] = max(v[A[rt].ls], v[A[rt].rs]); }

int merge(int x, int y, int l, int r) {
if (!x || !y) return x | y;
if (l == r) { v[x].first += v[y].first; return x; }
int mid = (l + r) >> 1;
A[x].ls = merge(A[x].ls, A[y].ls, l, mid);
A[x].rs = merge(A[x].rs, A[y].rs, mid + 1, r);
push_up(x);
return x;
}

void change(int &rt, int l, int r, int x, int vv) {
if (!rt) rt = ++cnt;
if (l == r) {
v[rt].first += vv, v[rt].second = -t[l];
return;
}
int mid = (l + r) >> 1;
if (x <= mid) change(A[rt].ls, l, mid, x, vv);
else change(A[rt].rs, mid + 1, r, x, vv);
push_up(rt);
}

int query(int rt) {
if (!rt || !v[rt].first) return 0;
return -v[rt].second;
}

}

namespace Tree {

int Begin[maxn], Next[maxn << 1], To[maxn << 1], e;
void add_edge(int x, int y) {
To[++e] = y;
Next[e] = Begin[x];
Begin[x] = e;
}

int fa[maxn][17], d[maxn];

void input() {
e = -1;
memset(Begin, -1, sizeof Begin);
for (int i = 1; i < n; i++) {
int x = read(), y = read();
add_edge(x, y), add_edge(y, x);
}
}

void dfs(int now, int f) {
d[now] = d[f] + 1, fa[now][0] = f;
for (int i = 1; i <= 16; i++) fa[now][i] = fa[fa[now][i - 1]][i - 1];
for (int i = Begin[now]; i + 1; i = Next[i]) {
int son = To[i];
if (son == f) continue;
dfs(son, now);
}
}

int lca(int x, int y) {
if (d[x] < d[y]) swap(x, y);
for (int i = 16; ~i; i--)
if (d[fa[x][i]] >= d[y]) x = fa[x][i];
if (x == y) return x;
for (int i = 16; ~i; i--)
if (fa[x][i] != fa[y][i]) x = fa[x][i], y = fa[y][i];
return fa[x][0];
}

void add(int x, int y, int z) {
int LCA = lca(x, y), f = fa[LCA][0];
ST::change(rt[x], 1, len, z, 1);
ST::change(rt[y], 1, len, z, 1);
ST::change(rt[LCA], 1, len, z, -1);
ST::change(rt[f], 1, len, z, -1);
}

void merge(int now, int f) {
for (int i = Begin[now]; i + 1; i = Next[i]) {
int son = To[i];
if (son == f) continue;
merge(son, now);
rt[now] = ST::merge(rt[now], rt[son], 1, len);
}
ans[now] = ST::query(rt[now]);
}

}

int main() {
#ifdef xunzhen
freopen("rain.in", "r", stdin);
freopen("rain.out", "w", stdout);
#endif

n = read(), m = read();
Tree::input(), Tree::dfs(1, 0);
for (int i = 1; i <= m; i++) {
op[i].x = read(), op[i].y = read(), t[i] = op[i].z = read();
}
sort(t + 1, t + m + 1);
len = unique(t + 1, t + m + 1) - t - 1;
for (int i = 1; i <= m; i++) {
op[i].z = lower_bound(t + 1, t + len + 1, op[i].z) - t;
Tree::add(op[i].x, op[i].y, op[i].z);
}

Tree::merge(1, 0);

for (int i = 1; i <= n; i++) printf("%d\n", ans[i]);

return 0;
}


## Summary

$$debug$$: 在离散化的时候，不要把原序列长度和离散化之后的长度搞混

posted @ 2018-09-26 22:11  xunzhen  阅读(140)  评论(0编辑  收藏  举报