#include <bits/stdc++.h>
#include <unordered_map>
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
using namespace std;
typedef long long ll;
typedef pair<ll, ll> pll;
#define MAX 201010
#define MAXS 18
#define INF 1000000000000000001
#define bb ' '
#define ln '\n'
struct segtree {
ll N;
ll s;
vector<ll> tree, l, r;
void update(ll x, ll a) {
x += s - 1;
tree[x] = a;
x /= 2;
while (x) tree[x] = max(tree[x * 2], tree[x * 2 + 1]), x /= 2;
}
ll query(ll low, ll high, ll loc = 1) {
if (l[loc] == low && r[loc] == high) return tree[loc];
if (r[loc * 2] >= high) return query(low, high, loc * 2);
if (l[loc * 2 + 1] <= low) return query(low, high, loc * 2 + 1);
return max(query(low, r[loc * 2], loc * 2), query(l[loc * 2 + 1], high, loc * 2 + 1));
}
void init(ll x = 1) {
if (x >= s) {
l[x] = r[x] = x - s + 1;
return;
}
init(x * 2);
init(x * 2 + 1);
l[x] = l[x * 2];
r[x] = r[x * 2 + 1];
}
segtree(ll n) {
N = n;
s = (ll)1 << (ll)ceil(log2(N));
tree.resize(2 * s + 1);
l.resize(2 * s + 1);
r.resize(2 * s + 1);
init();
}
};
vector<ll> adj[MAX], sav[MAX], savdis[MAX], rev[MAX];
ll dir[MAX], ddir[MAX], dddir[MAX];
vector<vector<ll>> chain;
vector<set<ll>> subtree, revtree;
vector<segtree> chainseg;
ll C[MAX], depth[MAX], mxdepv[MAX], prtval[MAX];
ll mxdep[MAX];
pll range[MAX];
ll sp[MAX][MAXS];
ll cnt;
ll num[MAX];
pll cnum[MAX];
ll ans[MAX];
ll arr[MAX];
ll init(ll x, ll p = 0, ll d = 0) {
sp[x][0] = p;
ll i;
for (i = 1; i < MAXS; i++) sp[x][i] = sp[sp[x][i - 1]][i - 1];
depth[x] = d;
ll sum = 1;
sav[x].resize(adj[x].size());
savdis[x].resize(adj[x].size());
rev[x].resize(adj[x].size());
for (auto v : adj[x]) {
if (v == p) continue;
sum += init(v, x, d + 1);
}
return num[x] = sum;
}
void calc(ll x, ll p = 0) {
ll i;
ll mx = 0;
mxdepv[x] = x;
for (i = 0; i < adj[x].size(); i++) {
if (adj[x][i] == p) continue;
calc(adj[x][i], x);
if (mx < depth[mxdepv[adj[x][i]]]) mx = depth[mxdepv[adj[x][i]]], mxdepv[x] = mxdepv[adj[x][i]];
sav[x][i] = mxdepv[adj[x][i]];
savdis[x][i] = depth[sav[x][i]] - depth[x];
}
ll cnt = 0;
ll vv, vvv;
vv = vvv = -1;
ll nv = -1;
ll nmx = 0;
for (auto v : adj[x]) {
if (v == p) continue;
if (depth[mxdepv[v]] == mx) cnt++, vvv = vv, vv = v;
else if (depth[mxdepv[v]] > nmx) nmx = depth[mxdepv[v]], nv = v;
}
if (cnt >= 2) {
for (i = 0; i < adj[x].size(); i++) {
if (adj[x][i] != p) {
rev[x][i] = (adj[x][i] == vv ? vvv : vv);
}
}
}
else {
for (i = 0; i < adj[x].size(); i++) {
if (adj[x][i] != p) {
rev[x][i] = (adj[x][i] == vv ? nv : vv);
}
}
}
for (i = 0; i < adj[x].size(); i++) {
if (adj[x][i] == p) continue;
if (rev[x][i] == -1) rev[x][i] = x;
else rev[x][i] = mxdepv[rev[x][i]];
}
}
void make_chain(ll x, ll p = 0) {
ll mx, mv;
mx = mv = 0;
chain[cnt].push_back(x);
cnum[x] = { cnt, chain[cnt].size() - 1 };
for (auto v : adj[x]) {
if (v == p) continue;
if (mx < num[v]) mx = num[v], mv = v;
}
if (mv) make_chain(mv, x);
for (auto v : adj[x]) {
if (v == p || v == mv) continue;
cnt++;
chain.push_back(vector<ll>());
make_chain(v, x);
}
}
void make_tree() {
ll i;
for (i = 0; i < chain.size(); i++) chainseg.push_back(segtree(chain[i].size()));
}
void update(ll v, ll x) {
chainseg[cnum[v].first].update(cnum[v].second + 1, x);
}
//1을 루트로 하는 LCA
ll lca(ll u, ll v) {
if (depth[u] != depth[v]) {
if (depth[u] < depth[v]) swap(u, v);
ll i;
for (i = MAXS - 1; i >= 0; i--) if (depth[sp[u][i]] >= depth[v]) u = sp[u][i];
}
if (u == v) return u;
ll i;
for (i = MAXS - 1; i >= 0; i--) if (sp[u][i] != sp[v][i]) u = sp[u][i], v = sp[v][i];
return sp[v][0];
}
//HLD query
ll mxval(ll u, ll v) {
ll ans = 0;
ll l = lca(u, v);
while (cnum[u].first != cnum[l].first) ans = max(ans, chainseg[cnum[u].first].query(1, cnum[u].second + 1)), u = sp[chain[cnum[u].first][0]][0];
while (cnum[v].first != cnum[l].first) ans = max(ans, chainseg[cnum[v].first].query(1, cnum[v].second + 1)), v = sp[chain[cnum[v].first][0]][0];
ans = max(ans, chainseg[cnum[l].first].query(cnum[l].second + 1, cnum[u].second + 1));
ans = max(ans, chainseg[cnum[l].first].query(cnum[l].second + 1, cnum[v].second + 1));
return ans;
}
//두 정점 사이 거리
ll dis(ll u, ll v) { return depth[u] + depth[v] - 2 * depth[lca(u, v)]; }
//r이 루트, v의 x번째 부모
ll prtx(ll r, ll v, ll x) {
if (x == 0) return v;
ll rv = dis(r, v);
if (rv < x) return 0;
ll l = lca(r, v);
if (dis(l, v) < x) {
ll d = rv - x;
ll i;
for (i = MAXS - 1; i >= 0; i--) if (d - (1 << i) >= 0) d -= (1 << i), r = sp[r][i];
return r;
}
else {
ll i;
for (i = MAXS - 1; i >= 0; i--) if (x - (1 << i) >= 0) x -= (1 << i), v = sp[v][i];
return v;
}
}
ll getfar(ll v, ll ban) {
if (dir[v] != ban) return dir[v];
return ddir[v];
}
ll getfar(ll v, ll ban1, ll ban2) {
if (ban1 > ban2) swap(ban1, ban2);
if (ban2 == -1) return dir[v];
if (ban1 == -1) return getfar(v, ban2);
if (dir[v] != ban1 && dir[v] != ban2) return dir[v];
if (ddir[v] != ban1 && ddir[v] != ban2) return ddir[v];
return dddir[v];
}
ll getind(vector<ll>& v, ll c) {
return lower_bound(v.begin(), v.end(), c) - v.begin();
}
//r1 : previous root
void prop(ll r1, ll r2) {
if (ddir[r2] == -1) arr[r2] = savdis[r2][dir[r2]], update(r2, arr[r2]);
else arr[r2] = savdis[r2][dir[r2]] + savdis[r2][ddir[r2]], update(r2, arr[r2]);
ll ind = getind(adj[r1], r2);
ll f1 = getfar(r1, ind);
ll f2 = getfar(r1, ind, f1);
if (f1 == -1) arr[r1] = 0, update(r1, 0);
else if (f2 == -1) arr[r1] = savdis[r1][f1], update(r1, arr[r1]);
else arr[r1] = savdis[r1][f1] + savdis[r1][f2], update(r1, arr[r1]);
}
void dfs(ll x, ll p = 0) {
ll i;
for (i = 0; i < adj[x].size(); i++) {
ll fardir = getfar(adj[x][i], getind(adj[adj[x][i]], x));
ll farv = sav[x][i];
if (mxval(farv, adj[x][i]) >= savdis[x][i]) continue;
ll xx = (savdis[x][i] - 1) / 2;
ll root = prtx(x, farv, xx);
if (lca(root, x) == root) revtree[prtx(x, root, 1)].insert(C[x]);
else subtree[root].insert(C[x]);
}
for (auto v : adj[x]) {
if (v == p) continue;
ll p1, p2;
p1 = arr[x];
p2 = arr[v];
prop(x, v);
dfs(v, x);
arr[x] = p1;
arr[v] = p2;
update(x, arr[x]);
update(v, arr[v]);
}
}
ll mp[MAX];
ll anscnt;
void getans(ll x, ll p = 0) {
for (auto c : subtree[x]) {
if (!mp[c]) anscnt++;
mp[c]++;
}
for (auto c : revtree[x]) {
mp[c]--;
if (!mp[c]) anscnt--;
}
ans[x] = anscnt;
for (auto v : adj[x]) {
if (v == p) continue;
getans(v, x);
}
for (auto c : revtree[x]) {
if (!mp[c]) anscnt++;
mp[c]++;
}
for (auto c : subtree[x]) {
mp[c]--;
if (!mp[c]) anscnt--;
}
}
void calcp(ll x, ll p = 0) {
if (x != 1) {
ll tmp = getind(adj[x], p);
if (p == 1) sav[x][tmp] = rev[p][getind(adj[p], x)];
else {
ll v1 = rev[p][getind(adj[p], x)];
ll v2 = sav[p][getind(adj[p], sp[p][0])];
if (v1 > v2) swap(v1, v2);
if (dis(x, v1) >= dis(x, v2)) sav[x][tmp] = v1;
else sav[x][tmp] = v2;
}
savdis[x][tmp] = dis(x, sav[x][tmp]);
}
for (auto v : adj[x]) if (v != p) calcp(v, x);
}
signed main() {
ios::sync_with_stdio(false), cin.tie(0);
depth[0] = -1;
ll N, M;
cin >> N >> M;
ll i, j;
ll a, b;
for (i = 1; i < N; i++) cin >> a >> b, adj[a].push_back(b), adj[b].push_back(a);
for (i = 1; i <= N; i++) cin >> C[i];
for (i = 1; i <= N; i++) sort(adj[i].begin(), adj[i].end());
init(1);
calc(1);
calcp(1);
cnt = 0;
chain.push_back(vector<ll>());
make_chain(1);
make_tree();
for (i = 1; i <= N; i++) {
ll mx = 0, mv = 0;
dir[i] = ddir[i] = dddir[i] = -1;
for (j = 0; j < adj[i].size(); j++) if (mx < dis(i, sav[i][j])) mx = dis(i, sav[i][j]), dir[i] = j;
mx = 0;
for (j = 0; j < adj[i].size(); j++) {
if (j == dir[i]) continue;
if (mx < dis(i, sav[i][j])) mx = dis(i, sav[i][j]), ddir[i] = j;
}
mx = 0;
for (j = 0; j < adj[i].size(); j++) {
if (j == dir[i] || j == ddir[i]) continue;
if (mx < dis(i, sav[i][j])) mx = dis(i, sav[i][j]), dddir[i] = j;
}
if (i != 1) {
ll p = getind(adj[i], sp[i][0]);
ll r = getfar(i, p);
ll rr = getfar(i, p, r);
ll xx = 0;
if (r != -1) xx += dis(i, sav[i][r]);
if (rr != -1) xx += dis(i, sav[i][rr]);
arr[i] = xx;
update(i, xx);
}
else {
ll dd;
dd = ddir[1];
if (dd == -1) arr[1] = depth[sav[1][dir[1]]];
else arr[1] = depth[sav[1][dd]] + depth[sav[1][dir[1]]];
update(1, arr[1]);
}
}
subtree.resize(N + 1);
revtree.resize(N + 1);
dfs(1);
for (i = 1; i <= N; i++) {
for (auto c : revtree[i]) {
if (!mp[c]) anscnt++;
mp[c]++;
}
}
getans(1);
for (i = 1; i <= N; i++) cout << ans[i] << ln;
}
Compilation message
joi2019_ho_t5.cpp: In function 'void calc(ll, ll)':
joi2019_ho_t5.cpp:82:16: warning: comparison of integer expressions of different signedness: 'll' {aka 'long long int'} and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
82 | for (i = 0; i < adj[x].size(); i++) {
| ~~^~~~~~~~~~~~~~~
joi2019_ho_t5.cpp:100:17: warning: comparison of integer expressions of different signedness: 'll' {aka 'long long int'} and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
100 | for (i = 0; i < adj[x].size(); i++) {
| ~~^~~~~~~~~~~~~~~
joi2019_ho_t5.cpp:107:17: warning: comparison of integer expressions of different signedness: 'll' {aka 'long long int'} and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
107 | for (i = 0; i < adj[x].size(); i++) {
| ~~^~~~~~~~~~~~~~~
joi2019_ho_t5.cpp:113:16: warning: comparison of integer expressions of different signedness: 'll' {aka 'long long int'} and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
113 | for (i = 0; i < adj[x].size(); i++) {
| ~~^~~~~~~~~~~~~~~
joi2019_ho_t5.cpp: In function 'void make_tree()':
joi2019_ho_t5.cpp:138:16: warning: comparison of integer expressions of different signedness: 'll' {aka 'long long int'} and 'std::vector<std::vector<long long int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
138 | for (i = 0; i < chain.size(); i++) chainseg.push_back(segtree(chain[i].size()));
| ~~^~~~~~~~~~~~~~
joi2019_ho_t5.cpp: In function 'void dfs(ll, ll)':
joi2019_ho_t5.cpp:213:16: warning: comparison of integer expressions of different signedness: 'll' {aka 'long long int'} and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
213 | for (i = 0; i < adj[x].size(); i++) {
| ~~^~~~~~~~~~~~~~~
joi2019_ho_t5.cpp:214:6: warning: unused variable 'fardir' [-Wunused-variable]
214 | ll fardir = getfar(adj[x][i], getind(adj[adj[x][i]], x));
| ^~~~~~
joi2019_ho_t5.cpp: In function 'int main()':
joi2019_ho_t5.cpp:295:17: warning: comparison of integer expressions of different signedness: 'll' {aka 'long long int'} and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
295 | for (j = 0; j < adj[i].size(); j++) if (mx < dis(i, sav[i][j])) mx = dis(i, sav[i][j]), dir[i] = j;
| ~~^~~~~~~~~~~~~~~
joi2019_ho_t5.cpp:297:17: warning: comparison of integer expressions of different signedness: 'll' {aka 'long long int'} and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
297 | for (j = 0; j < adj[i].size(); j++) {
| ~~^~~~~~~~~~~~~~~
joi2019_ho_t5.cpp:302:17: warning: comparison of integer expressions of different signedness: 'll' {aka 'long long int'} and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
302 | for (j = 0; j < adj[i].size(); j++) {
| ~~^~~~~~~~~~~~~~~
joi2019_ho_t5.cpp:293:14: warning: unused variable 'mv' [-Wunused-variable]
293 | ll mx = 0, mv = 0;
| ^~
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
13 ms |
19180 KB |
Output is correct |
2 |
Correct |
19 ms |
20456 KB |
Output is correct |
3 |
Correct |
18 ms |
19872 KB |
Output is correct |
4 |
Correct |
23 ms |
20324 KB |
Output is correct |
5 |
Correct |
20 ms |
20500 KB |
Output is correct |
6 |
Correct |
23 ms |
20556 KB |
Output is correct |
7 |
Correct |
21 ms |
20428 KB |
Output is correct |
8 |
Correct |
20 ms |
20564 KB |
Output is correct |
9 |
Correct |
21 ms |
20512 KB |
Output is correct |
10 |
Correct |
24 ms |
20572 KB |
Output is correct |
11 |
Correct |
21 ms |
20556 KB |
Output is correct |
12 |
Correct |
18 ms |
20720 KB |
Output is correct |
13 |
Correct |
23 ms |
20488 KB |
Output is correct |
14 |
Correct |
25 ms |
20556 KB |
Output is correct |
15 |
Correct |
20 ms |
20560 KB |
Output is correct |
16 |
Correct |
18 ms |
20812 KB |
Output is correct |
17 |
Correct |
25 ms |
20652 KB |
Output is correct |
18 |
Correct |
21 ms |
20472 KB |
Output is correct |
19 |
Correct |
21 ms |
20556 KB |
Output is correct |
20 |
Correct |
25 ms |
20656 KB |
Output is correct |
21 |
Correct |
21 ms |
20428 KB |
Output is correct |
22 |
Correct |
19 ms |
20540 KB |
Output is correct |
23 |
Correct |
21 ms |
20556 KB |
Output is correct |
24 |
Correct |
20 ms |
20520 KB |
Output is correct |
25 |
Correct |
21 ms |
20516 KB |
Output is correct |
26 |
Correct |
19 ms |
20668 KB |
Output is correct |
27 |
Correct |
23 ms |
20696 KB |
Output is correct |
28 |
Correct |
23 ms |
20648 KB |
Output is correct |
29 |
Correct |
21 ms |
20548 KB |
Output is correct |
30 |
Correct |
18 ms |
20812 KB |
Output is correct |
31 |
Correct |
25 ms |
20648 KB |
Output is correct |
32 |
Correct |
21 ms |
20484 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
826 ms |
90808 KB |
Output is correct |
2 |
Correct |
1468 ms |
94792 KB |
Output is correct |
3 |
Correct |
199 ms |
36348 KB |
Output is correct |
4 |
Correct |
1537 ms |
143288 KB |
Output is correct |
5 |
Execution timed out |
2103 ms |
136384 KB |
Time limit exceeded |
6 |
Halted |
0 ms |
0 KB |
- |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
1211 ms |
119968 KB |
Output is correct |
2 |
Execution timed out |
2075 ms |
138804 KB |
Time limit exceeded |
3 |
Halted |
0 ms |
0 KB |
- |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
13 ms |
19180 KB |
Output is correct |
2 |
Correct |
19 ms |
20456 KB |
Output is correct |
3 |
Correct |
18 ms |
19872 KB |
Output is correct |
4 |
Correct |
23 ms |
20324 KB |
Output is correct |
5 |
Correct |
20 ms |
20500 KB |
Output is correct |
6 |
Correct |
23 ms |
20556 KB |
Output is correct |
7 |
Correct |
21 ms |
20428 KB |
Output is correct |
8 |
Correct |
20 ms |
20564 KB |
Output is correct |
9 |
Correct |
21 ms |
20512 KB |
Output is correct |
10 |
Correct |
24 ms |
20572 KB |
Output is correct |
11 |
Correct |
21 ms |
20556 KB |
Output is correct |
12 |
Correct |
18 ms |
20720 KB |
Output is correct |
13 |
Correct |
23 ms |
20488 KB |
Output is correct |
14 |
Correct |
25 ms |
20556 KB |
Output is correct |
15 |
Correct |
20 ms |
20560 KB |
Output is correct |
16 |
Correct |
18 ms |
20812 KB |
Output is correct |
17 |
Correct |
25 ms |
20652 KB |
Output is correct |
18 |
Correct |
21 ms |
20472 KB |
Output is correct |
19 |
Correct |
21 ms |
20556 KB |
Output is correct |
20 |
Correct |
25 ms |
20656 KB |
Output is correct |
21 |
Correct |
21 ms |
20428 KB |
Output is correct |
22 |
Correct |
19 ms |
20540 KB |
Output is correct |
23 |
Correct |
21 ms |
20556 KB |
Output is correct |
24 |
Correct |
20 ms |
20520 KB |
Output is correct |
25 |
Correct |
21 ms |
20516 KB |
Output is correct |
26 |
Correct |
19 ms |
20668 KB |
Output is correct |
27 |
Correct |
23 ms |
20696 KB |
Output is correct |
28 |
Correct |
23 ms |
20648 KB |
Output is correct |
29 |
Correct |
21 ms |
20548 KB |
Output is correct |
30 |
Correct |
18 ms |
20812 KB |
Output is correct |
31 |
Correct |
25 ms |
20648 KB |
Output is correct |
32 |
Correct |
21 ms |
20484 KB |
Output is correct |
33 |
Correct |
826 ms |
90808 KB |
Output is correct |
34 |
Correct |
1468 ms |
94792 KB |
Output is correct |
35 |
Correct |
199 ms |
36348 KB |
Output is correct |
36 |
Correct |
1537 ms |
143288 KB |
Output is correct |
37 |
Execution timed out |
2103 ms |
136384 KB |
Time limit exceeded |
38 |
Halted |
0 ms |
0 KB |
- |