|
5 | 5 | //! https://youtu.be/wDwaMo5xa-k |
6 | 6 | //! @code |
7 | 7 | //! vector<basic_string<int>> g(n); |
8 | | -//! edge_cd(g, [&](int cent, int m) { |
9 | | -//! // subtrees of [0, m) of g[cent]: 1st edge-set |
10 | | -//! // subtrees of [m, sz(g[cent])): 2nd edge-set |
| 8 | +//! edge_cd(g, [&](int c, int m) { |
| 9 | +//! // subtrees of [0, m) of g[c]: 1st edge-set |
| 10 | +//! // subtrees of [m, sz(g[c])): 2nd edge-set |
11 | 11 | //! }); |
12 | 12 | //! @endcode |
13 | 13 | //! handle single-edge-paths separately |
14 | 14 | //! @time O(n logφ n) |
15 | 15 | //! @space O(n) |
16 | 16 | template<class G> void edge_cd(vector<G>& g, auto f) { |
17 | | - vi siz(sz(g)); |
| 17 | + vi s(sz(g)); |
18 | 18 | auto ctd = [&](auto ctd, int u, int p, int m) -> int { |
19 | | - siz[u] = 1; |
| 19 | + s[u] = 1; |
20 | 20 | for (int v : g[u]) |
21 | 21 | if (v != p) { |
22 | 22 | if (int c = ctd(ctd, v, u, m); c != -1) return c; |
23 | | - siz[u] += siz[v]; |
| 23 | + s[u] += s[v]; |
24 | 24 | } |
25 | | - return 2 * siz[u] > m ? siz[p] = m + 1 - siz[u], |
26 | | - u : -1; |
| 25 | + return 2 * s[u] > m ? s[p] = m + 1 - s[u], u : -1; |
27 | 26 | }; |
28 | 27 | auto dfs = [&](auto dfs, int u, int m) { |
29 | 28 | if (m < 2) return; |
30 | 29 | u = ctd(ctd, u, u, m); |
31 | 30 | int sum = 0; |
32 | 31 | auto it = partition(all(g[u]), [&](int v) { |
33 | | - ll x = sum + siz[v]; |
| 32 | + ll x = sum + s[v]; |
34 | 33 | return x * x < m * (m - x) ? sum = x : 0; |
35 | 34 | }); |
36 | 35 | f(u, it - begin(g[u])); |
|
0 commit comments