Skip to content

Commit 19ad2e3

Browse files
authored
[20250227] BOJ / D4 / 트리와 K번째 수 / 권혁준
1 parent b69c170 commit 19ad2e3

File tree

1 file changed

+107
-0
lines changed

1 file changed

+107
-0
lines changed
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
```cpp
2+
3+
#include <iostream>
4+
#include <vector>
5+
#include <algorithm>
6+
#include <cmath>
7+
using namespace std;
8+
#define AA(p,q,s) p.begin(), p.end(), q.begin(), q.end(), s.begin()
9+
int A[100001]{}, par[100001]{}, sz[100001]{}, dep[100001]{}, cn[100001]{}, ci[100001]{};
10+
vector<vector<int>> V(100001), C(100001);
11+
vector<vector<int>> seg[100001]{};
12+
13+
int dfs(int n, int p) {
14+
par[n] = p, sz[n] = 1;
15+
for (int i : V[n]) if (i != p) sz[n] += dfs(i, n);
16+
return sz[n];
17+
}
18+
19+
void hld(int n, int p, int s, int d) {
20+
dep[n] = d, cn[n] = s, ci[n] = C[s].size();
21+
C[s].push_back(n);
22+
int h = -1;
23+
for (int i : V[n]) if (i != p && (h == -1 || sz[i] > sz[h])) h = i;
24+
if (h != -1) hld(h, n, s, d);
25+
for (int i : V[n]) if (i != p && i != h) hld(i, n, i, d + 1);
26+
}
27+
28+
void init(int id, int s, int e, int n) {
29+
if (s == e) {
30+
seg[id][n] = { A[C[id][s]] };
31+
return;
32+
}
33+
int m = (s + e) >> 1;
34+
init(id, s, m, n * 2);
35+
init(id, m + 1, e, n * 2 + 1);
36+
seg[id][n].resize(seg[id][n * 2].size() + seg[id][n * 2 + 1].size());
37+
merge(AA(seg[id][n * 2], seg[id][n * 2 + 1], seg[id][n]));
38+
}
39+
40+
int find(int id, int s, int e, int l, int r, int k, int n) {
41+
if (l > r || l > e || r < s) return 0;
42+
if (l <= s && e <= r) return lower_bound(seg[id][n].begin(), seg[id][n].end(), k) - seg[id][n].begin();
43+
int m = (s + e) >> 1;
44+
return find(id, s, m, l, r, k, n * 2) + find(id, m + 1, e, l, r, k, n * 2 + 1);
45+
}
46+
47+
int cnt(int a, int b, int k) {
48+
int res = 0;
49+
while (cn[a] != cn[b]) {
50+
if (dep[a] > dep[b]) {
51+
res += find(cn[a], 0, C[cn[a]].size() - 1, 0, ci[a], k, 1);
52+
a = par[cn[a]];
53+
}
54+
else {
55+
res += find(cn[b], 0, C[cn[b]].size() - 1, 0, ci[b], k, 1);
56+
b = par[cn[b]];
57+
}
58+
}
59+
if (ci[a] > ci[b]) swap(a, b);
60+
res += find(cn[a], 0, C[cn[a]].size() - 1, ci[a], ci[b], k, 1);
61+
return res;
62+
}
63+
64+
int M[100000]{};
65+
66+
int main() {
67+
cin.tie(0)->sync_with_stdio(0);
68+
69+
int N, Q;
70+
cin >> N >> Q;
71+
vector<pair<int, int>> Value;
72+
for (int i = 1; i <= N; i++) {
73+
cin >> A[i];
74+
Value.emplace_back(A[i], i);
75+
}
76+
sort(Value.begin(), Value.end());
77+
for (int i = 0; i < N; i++) M[i] = Value[i].first, A[Value[i].second] = i;
78+
79+
80+
for (int i = 1, a, b; i < N; i++) {
81+
cin >> a >> b;
82+
V[a].push_back(b);
83+
V[b].push_back(a);
84+
}
85+
86+
dfs(1, 0);
87+
hld(1, 0, 1, 0);
88+
89+
for (int i = 1; i <= N; i++) if (!C[i].empty()) {
90+
seg[i].resize((1 << ((int)log2(C[i].size()) + 2)) + 1);
91+
init(i, 0, C[i].size() - 1, 1);
92+
}
93+
94+
for (int x, y, k; Q--;) {
95+
cin >> x >> y >> k;
96+
long long s = 0, e = 100000, m = (s + e + 1) >> 1;
97+
while (s < e) {
98+
if (cnt(x, y, m) < k) s = m;
99+
else e = m - 1;
100+
m = (s + e + 1) >> 1;
101+
}
102+
cout << M[m] << '\n';
103+
}
104+
105+
}
106+
107+
```

0 commit comments

Comments
 (0)