#include <bits/stdc++.h>
//#pragma GCC target("avx2")
//#pragma GCC optimize("O3,unroll-loops")
#define fastIO ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0)
#define endl '\n'
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
using namespace std;
using ll [[maybe_unused]] = long long;
using ull [[maybe_unused]] = unsigned long long;
using lll [[maybe_unused]] = __int128;
using lld [[maybe_unused]] = long double;
using llld [[maybe_unused]] = __float128;
template<typename T> using graph [[maybe_unused]] = vector<vector<pair<int,T>>>;
template<typename T> using matrix [[maybe_unused]] = vector<vector<T>>;
const ll INF = 0x3f3f3f3f3f3f3f3f;
/**
* @brief Centroid Tree implementation
*/
class CentroidTree {
int n, root;
int MAX_BIT;
graph<int> g;
vector<int> sz, // size of the subtree
depth, // depth of the node
tree, // centroid tree(tree[i] = parent of i at the centroid tree)
S, T, E; // Euler Tour
vector<ll> dist; // distance from the initial root
int pw = 0;
int dfs(int u, int p) {
sz[u] = 1;
E[++pw] = u;
S[u] = pw;
for (const auto& [v, w]: g[u]) {
if (v == p) continue;
depth[v] = depth[u] + 1;
dist[v] = dist[u] + w;
sz[u] += dfs(v, u);
E[++pw] = u;
}
return sz[u];
}
vector<int> pw2, lg2;
vector<vector<pair<int,int>>> ST;
void lca_prepare(){
pw2.resize(MAX_BIT);
pw2[0] = 1;
for (int i = 1; i < MAX_BIT; i++) pw2[i] = pw2[i - 1] << 1;
lg2.resize(n * 2);
fill(lg2.begin(), lg2.end(), -1);
for (int i = 0; i < MAX_BIT; i++) if (pw2[i] < n * 2) lg2[pw2[i]] = i;
for (int i = 1; i < n * 2; i++) if (lg2[i] == -1) lg2[i] = lg2[i - 1];
ST.resize(MAX_BIT, vector<pair<int,int>>(n * 2));
for (int i = 1; i < n * 2; i++) ST[0][i] = {depth[E[i]], E[i]};
for(int k = 1; k < MAX_BIT; k++) {
for (int i = 1; i < n * 2; i++) {
if (i + pw2[k - 1] > n * 2) continue;
ST[k][i] = min(ST[k - 1][i], ST[k - 1][i + pw2[k - 1]]);
}
}
}
int lca(int u, int v) {
int l = S[u], r = S[v];
if (l > r) swap(l, r);
int k = lg2[r - l + 1];
return min(ST[k][l], ST[k][r - pw2[k] + 1]).second;
}
ll get_dist(int u, int v) {
return dist[u] + dist[v] - 2 * dist[lca(u, v)];
}
int get_centroid(int u) {
for (const auto& [v, w]: g[u]) {
if (sz[u] >> 1 < sz[v] && sz[v] < sz[u]) {
sz[u] -= sz[v];
sz[v] += sz[u];
return get_centroid(v);
}
}
return u;
}
void build_centroid_tree(int u, int p = -1) {
u = get_centroid(u);
if (p == -1) tree[u] = u;
else tree[u] = p;
for (const auto& [v, _]: g[u])
if (sz[v] < sz[u])
build_centroid_tree(v, u);
}
public:
CentroidTree() = default;
explicit
CentroidTree(const graph<int>& g, int root = 1) : g(g), n((int)g.size()), root(root) {
sz.resize(n, 0);
depth.resize(n, 0);
dist.resize(n, 0);
S.resize(n), T.resize(n), E.resize(n * 2);
tree.resize(n);
MAX_BIT = std::ceil(std::log2(n)) + 1;
dfs(root, -1);
lca_prepare();
build_centroid_tree(root);
x_dist.resize(n, INF);
}
vector<ll> x_dist;
void update(int u) {
for (int v = u;; v = tree[v]) {
x_dist[v] = min(x_dist[v], get_dist(u, v));
if (tree[v] == v) break;
}
}
ll query(int u) {
ll res = INF;
for (int v = u;; v = tree[v]) {
res = min(res, x_dist[v] + get_dist(u, v));
if (tree[v] == v) break;
}
return res;
}
void clear(int u) {
for (int v = u;; v = tree[v]) {
x_dist[v] = INF;
if (tree[v] == v) break;
}
}
}; // class CentroidTree
graph<int> g;
CentroidTree solver;
void Init(int N, int A[], int B[], int D[]) {
g.resize(N + 1);
for (int i = 0; i < N - 1; i++) {
g[A[i]+1].emplace_back(B[i]+1, D[i]);
g[B[i]+1].emplace_back(A[i]+1, D[i]);
}
solver = CentroidTree(g);
}
ll Query(int S, int X[], int T, int Y[]) {
ll ans = INF;
for (int i = 0; i < S; i++) solver.update(X[i]+1);
for (int i = 0; i < T; i++) ans = min(ans, solver.query(Y[i]+1));
for (int i = 0; i < S; i++) solver.clear(X[i]+1);
return ans;
}
Compilation message
factories.cpp: In constructor 'CentroidTree::CentroidTree(graph<int>&, int)':
factories.cpp:24:16: warning: 'CentroidTree::g' will be initialized after [-Wreorder]
24 | graph<int> g;
| ^
factories.cpp:22:9: warning: 'int CentroidTree::n' [-Wreorder]
22 | int n, root;
| ^
factories.cpp:106:5: warning: when initialized here [-Wreorder]
106 | CentroidTree(const graph<int>& g, int root = 1) : g(g), n((int)g.size()), root(root) {
| ^~~~~~~~~~~~
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
6 ms |
16988 KB |
Output is correct |
2 |
Correct |
244 ms |
22968 KB |
Output is correct |
3 |
Correct |
324 ms |
22864 KB |
Output is correct |
4 |
Correct |
305 ms |
22868 KB |
Output is correct |
5 |
Correct |
328 ms |
32564 KB |
Output is correct |
6 |
Correct |
132 ms |
32340 KB |
Output is correct |
7 |
Correct |
317 ms |
32340 KB |
Output is correct |
8 |
Correct |
322 ms |
32336 KB |
Output is correct |
9 |
Correct |
313 ms |
32536 KB |
Output is correct |
10 |
Correct |
132 ms |
32448 KB |
Output is correct |
11 |
Correct |
310 ms |
32320 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
3 ms |
16984 KB |
Output is correct |
2 |
Correct |
851 ms |
264816 KB |
Output is correct |
3 |
Correct |
964 ms |
265448 KB |
Output is correct |
4 |
Correct |
435 ms |
268220 KB |
Output is correct |
5 |
Correct |
1211 ms |
278528 KB |
Output is correct |
6 |
Correct |
1068 ms |
265676 KB |
Output is correct |
7 |
Correct |
731 ms |
66868 KB |
Output is correct |
8 |
Correct |
224 ms |
67792 KB |
Output is correct |
9 |
Correct |
747 ms |
68776 KB |
Output is correct |
10 |
Correct |
731 ms |
67300 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
6 ms |
16988 KB |
Output is correct |
2 |
Correct |
244 ms |
22968 KB |
Output is correct |
3 |
Correct |
324 ms |
22864 KB |
Output is correct |
4 |
Correct |
305 ms |
22868 KB |
Output is correct |
5 |
Correct |
328 ms |
32564 KB |
Output is correct |
6 |
Correct |
132 ms |
32340 KB |
Output is correct |
7 |
Correct |
317 ms |
32340 KB |
Output is correct |
8 |
Correct |
322 ms |
32336 KB |
Output is correct |
9 |
Correct |
313 ms |
32536 KB |
Output is correct |
10 |
Correct |
132 ms |
32448 KB |
Output is correct |
11 |
Correct |
310 ms |
32320 KB |
Output is correct |
12 |
Correct |
3 ms |
16984 KB |
Output is correct |
13 |
Correct |
851 ms |
264816 KB |
Output is correct |
14 |
Correct |
964 ms |
265448 KB |
Output is correct |
15 |
Correct |
435 ms |
268220 KB |
Output is correct |
16 |
Correct |
1211 ms |
278528 KB |
Output is correct |
17 |
Correct |
1068 ms |
265676 KB |
Output is correct |
18 |
Correct |
731 ms |
66868 KB |
Output is correct |
19 |
Correct |
224 ms |
67792 KB |
Output is correct |
20 |
Correct |
747 ms |
68776 KB |
Output is correct |
21 |
Correct |
731 ms |
67300 KB |
Output is correct |
22 |
Correct |
1229 ms |
288200 KB |
Output is correct |
23 |
Correct |
1555 ms |
289420 KB |
Output is correct |
24 |
Correct |
1600 ms |
288172 KB |
Output is correct |
25 |
Correct |
1740 ms |
290416 KB |
Output is correct |
26 |
Correct |
1619 ms |
288476 KB |
Output is correct |
27 |
Correct |
1935 ms |
299432 KB |
Output is correct |
28 |
Correct |
553 ms |
292916 KB |
Output is correct |
29 |
Correct |
1653 ms |
288440 KB |
Output is correct |
30 |
Correct |
1641 ms |
288092 KB |
Output is correct |
31 |
Correct |
1627 ms |
288456 KB |
Output is correct |
32 |
Correct |
784 ms |
83100 KB |
Output is correct |
33 |
Correct |
226 ms |
82092 KB |
Output is correct |
34 |
Correct |
526 ms |
79712 KB |
Output is correct |
35 |
Correct |
554 ms |
79928 KB |
Output is correct |
36 |
Correct |
721 ms |
79928 KB |
Output is correct |
37 |
Correct |
738 ms |
79928 KB |
Output is correct |