#include <bits/stdc++.h> using namespace std; using i64 = long long; constexpr int N = 1e5 + 10, B = 500, S = N / B * 10; constexpr i64 inf = 1e18; int n, all, rt, ts, sz[N], dfn[N], ans[N], vis[N], col[N]; i64 r[N], dis[N]; vector<pair<int, i64>> G[N]; vector<pair<int, int>> par[N]; vector<int> pos[N]; bitset<N> pre[S]; int tot; struct Centroid { vector<int> s, top; vector<i64> f, dep; vector<int> perm; int n, rt, p; int st; void init(int u) { rt = u, n = s.size(); f.resize(n), dep.resize(n), top.resize(n); sort(s.begin(), s.end(), [&] (int x, int y) {return dis[x] < dis[y];}); for(int i = 0; i < n; i ++) { f[i] = -inf, dep[i] = dis[s[i]], top[i] = col[s[i]]; par[s[i]].emplace_back(rt, i); } } void getbitset() { int cnt = perm.size() / B; st = tot; for(int i = 1; i <= cnt; i ++) { if(i > 1) pre[st + i] = pre[st + i - 1]; for(int j = (i - 1) * B; j < min(int(perm.size()), i * B); j ++) { pre[st + i][perm[j]] = 1; } } tot += cnt; assert(tot + 10 < S); } void clear() { p = 0; } }ds[N]; vector<int> id[N]; void findrt(int u, int par) { int mx = 0; sz[u] = 1; for(auto [v, w] : G[u]) if(!vis[v] && v != par) { findrt(v, u); sz[u] += sz[v]; mx = max(mx, sz[v]); } mx = max(mx, all - sz[u]); if(2 * mx <= all) rt = u; } void dfs(int u, int par, int c, vector<int> &s) { s.emplace_back(u); for(auto [v, w] : G[u]) if(v != par && !vis[v]) { dis[v] = dis[u] + w, col[v] = c ? c : v; dfs(v, u, col[v], s); } } void build(int u) { vis[u] = 1; dis[u] = 0, col[u] = 0; dfs(u, u, 0, ds[u].s); ds[u].init(u); dfn[++ ts] = u; for(auto [v, w] : G[u]) if(!vis[v]) { findrt(v, u), rt = 0, all = sz[v], findrt(v, u), build(rt); } } int main() { // freopen("in.txt", "r", stdin); ios::sync_with_stdio(false), cin.tie(0); cin >> n; for(int i = 1; i <= n; i ++) cin >> r[i]; for(int i = 1; i < n; i ++) { int u, v; i64 w; cin >> u >> v >> w; G[u].emplace_back(v, w); G[v].emplace_back(u, w); } all = n, findrt(1, 1); int root = rt; build(rt); for(int i = n; i >= 1; i --) { int u = dfn[i], m = ds[u].n; for(auto v : ds[u].s) ds[v].clear(); static int id[N], use[N], ts = 0; ts ++; iota(id, id + m, 0); ds[u].f[par[u].back().second] = 0; for(i64 &x : ds[u].f) x = x >= 0 ? max(x, r[u]) : x; for(int i = 0; i < m; i ++) col[ds[u].s[i]] = ds[u].top[i]; sort(id, id + m, [&] (int x, int y) {return ds[u].f[x] < ds[u].f[y];}); int dep = par[u].size() - 1; vector<i64> w(dep, -inf); function<void(Centroid&, i64)> relax; auto &perm = ds[u].perm; function<void(int)> remove = [&] (int u) { use[u] = ts; perm.emplace_back(u); for(int i = 0; i < dep; i ++) { auto [x, id] = par[u][i]; w[i] = max(w[i], r[u] - ds[x].dep[id]); } for(int i = dep; i < par[u].size(); i ++) { auto [x, id] = par[u][i]; relax(ds[x], r[u] - ds[x].dep[id]); } }; relax = [&] (Centroid &x, i64 w) { while(x.p < x.n && x.dep[x.p] <= w) { x.p ++; if(use[x.s[x.p - 1]] != ts) { remove(x.s[x.p - 1]); } } }; for(int i = 0; i < m; i ++) { int v = id[i], z = ds[u].s[v]; relax(ds[u], ds[u].f[v]); for(int i = 0; i < dep; i ++) { auto [x, id] = par[z][i]; ds[x].f[id] = max(ds[x].f[id], w[i]); } pos[z].emplace_back(ds[u].perm.size()); } } for(int i = 1; i <= n; i ++) { ds[i].getbitset(); } bitset<N> cur; for(int i = 1; i <= n; i ++) { reverse(pos[i].begin(), pos[i].end()); cur.reset(); for(int j = 0; j < par[i].size(); j ++) { auto [x, id] = par[i][j]; int k = pos[i][j] - 1; if(k >= B) cur |= pre[ds[x].st + k / B]; for(int lim = k / B * B; k >= lim; k --) cur[ds[x].perm[k]] = 1; } cout << cur.count() << " \n"[i == n]; } return 0; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | #include <bits/stdc++.h> using namespace std; using i64 = long long; constexpr int N = 1e5 + 10, B = 500, S = N / B * 10; constexpr i64 inf = 1e18; int n, all, rt, ts, sz[N], dfn[N], ans[N], vis[N], col[N]; i64 r[N], dis[N]; vector<pair<int, i64>> G[N]; vector<pair<int, int>> par[N]; vector<int> pos[N]; bitset<N> pre[S]; int tot; struct Centroid { vector<int> s, top; vector<i64> f, dep; vector<int> perm; int n, rt, p; int st; void init(int u) { rt = u, n = s.size(); f.resize(n), dep.resize(n), top.resize(n); sort(s.begin(), s.end(), [&] (int x, int y) {return dis[x] < dis[y];}); for(int i = 0; i < n; i ++) { f[i] = -inf, dep[i] = dis[s[i]], top[i] = col[s[i]]; par[s[i]].emplace_back(rt, i); } } void getbitset() { int cnt = perm.size() / B; st = tot; for(int i = 1; i <= cnt; i ++) { if(i > 1) pre[st + i] = pre[st + i - 1]; for(int j = (i - 1) * B; j < min(int(perm.size()), i * B); j ++) { pre[st + i][perm[j]] = 1; } } tot += cnt; assert(tot + 10 < S); } void clear() { p = 0; } }ds[N]; vector<int> id[N]; void findrt(int u, int par) { int mx = 0; sz[u] = 1; for(auto [v, w] : G[u]) if(!vis[v] && v != par) { findrt(v, u); sz[u] += sz[v]; mx = max(mx, sz[v]); } mx = max(mx, all - sz[u]); if(2 * mx <= all) rt = u; } void dfs(int u, int par, int c, vector<int> &s) { s.emplace_back(u); for(auto [v, w] : G[u]) if(v != par && !vis[v]) { dis[v] = dis[u] + w, col[v] = c ? c : v; dfs(v, u, col[v], s); } } void build(int u) { vis[u] = 1; dis[u] = 0, col[u] = 0; dfs(u, u, 0, ds[u].s); ds[u].init(u); dfn[++ ts] = u; for(auto [v, w] : G[u]) if(!vis[v]) { findrt(v, u), rt = 0, all = sz[v], findrt(v, u), build(rt); } } int main() { // freopen("in.txt", "r", stdin); ios::sync_with_stdio(false), cin.tie(0); cin >> n; for(int i = 1; i <= n; i ++) cin >> r[i]; for(int i = 1; i < n; i ++) { int u, v; i64 w; cin >> u >> v >> w; G[u].emplace_back(v, w); G[v].emplace_back(u, w); } all = n, findrt(1, 1); int root = rt; build(rt); for(int i = n; i >= 1; i --) { int u = dfn[i], m = ds[u].n; for(auto v : ds[u].s) ds[v].clear(); static int id[N], use[N], ts = 0; ts ++; iota(id, id + m, 0); ds[u].f[par[u].back().second] = 0; for(i64 &x : ds[u].f) x = x >= 0 ? max(x, r[u]) : x; for(int i = 0; i < m; i ++) col[ds[u].s[i]] = ds[u].top[i]; sort(id, id + m, [&] (int x, int y) {return ds[u].f[x] < ds[u].f[y];}); int dep = par[u].size() - 1; vector<i64> w(dep, -inf); function<void(Centroid&, i64)> relax; auto &perm = ds[u].perm; function<void(int)> remove = [&] (int u) { use[u] = ts; perm.emplace_back(u); for(int i = 0; i < dep; i ++) { auto [x, id] = par[u][i]; w[i] = max(w[i], r[u] - ds[x].dep[id]); } for(int i = dep; i < par[u].size(); i ++) { auto [x, id] = par[u][i]; relax(ds[x], r[u] - ds[x].dep[id]); } }; relax = [&] (Centroid &x, i64 w) { while(x.p < x.n && x.dep[x.p] <= w) { x.p ++; if(use[x.s[x.p - 1]] != ts) { remove(x.s[x.p - 1]); } } }; for(int i = 0; i < m; i ++) { int v = id[i], z = ds[u].s[v]; relax(ds[u], ds[u].f[v]); for(int i = 0; i < dep; i ++) { auto [x, id] = par[z][i]; ds[x].f[id] = max(ds[x].f[id], w[i]); } pos[z].emplace_back(ds[u].perm.size()); } } for(int i = 1; i <= n; i ++) { ds[i].getbitset(); } bitset<N> cur; for(int i = 1; i <= n; i ++) { reverse(pos[i].begin(), pos[i].end()); cur.reset(); for(int j = 0; j < par[i].size(); j ++) { auto [x, id] = par[i][j]; int k = pos[i][j] - 1; if(k >= B) cur |= pre[ds[x].st + k / B]; for(int lim = k / B * B; k >= lim; k --) cur[ds[x].perm[k]] = 1; } cout << cur.count() << " \n"[i == n]; } return 0; } |