Skip to content

Commit a8c1a2e

Browse files
authored
Merge pull request #181 from AlgorithmWithGod/khj20006
[20250226] BOJ / P2 / 트리의 외심 / 권혁준
2 parents 88420eb + 10f6fdd commit a8c1a2e

File tree

2 files changed

+161
-0
lines changed

2 files changed

+161
-0
lines changed
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
```cpp
2+
3+
#include <iostream>
4+
#include <vector>
5+
#include <algorithm>
6+
#include <cmath>
7+
using namespace std;
8+
using ll = long long;
9+
10+
int D[32]{1};
11+
12+
int sol(int d, int s, int e);
13+
int ans(int x, int y);
14+
15+
int main()
16+
{
17+
cin.tie(0)->sync_with_stdio(0);
18+
19+
for (int i = 1; i < 32; i++) D[i] = D[i - 1] + i;
20+
int T, x, y;
21+
for (cin >> T; T--;) {
22+
cin >> x >> y;
23+
cout << ans(x, y) << '\n';
24+
}
25+
26+
}
27+
28+
int J(int x) {
29+
if (x <= 1) return x;
30+
int lg = log2(x);
31+
if (x == (1 << (lg + 1)) - 1) return lg + 1;
32+
if (x == (1 << (lg + 1)) - 2) return lg * 2;
33+
return lg + J(x - (1 << lg) + 1);
34+
}
35+
36+
int sol(int d, int s, int e) {
37+
if (s == e) return J(s + (1 << d) - 1);
38+
if (e == (1 << d)) {
39+
int res = max(d * 2, d + 1);
40+
if (s == (1 << d) - 1) return res;
41+
return max(res, d + ans(s, e - 2));
42+
}
43+
return d + ans(s, e);
44+
}
45+
46+
int ans(int x, int y) {
47+
if (y <= 5) {
48+
int arr[6] = { 0,1,2,2,3,4 };
49+
int mx = 0;
50+
for (int i = x; i <= y; i++) mx = max(mx, arr[i]);
51+
return mx;
52+
}
53+
int depX = log2(x);
54+
int depY = log2(y);
55+
int idxX = x - (1 << depX) + 1;
56+
int idxY = y - (1 << depY) + 1;
57+
if (depY - depX > 1) return max(D[depY - 1], sol(depY, 1, idxY));
58+
if (depY - depX == 1) return max(sol(depY, 1, idxY), sol(depX, idxX, (1 << depX)));
59+
return sol(depX, idxX, idxY);
60+
}
61+
62+
```
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
```cpp
2+
3+
#include <iostream>
4+
#include <vector>
5+
#include <algorithm>
6+
using namespace std;
7+
using ll = long long;
8+
9+
int N, Q;
10+
vector<vector<int>> V(100001);
11+
int par[100001][17]{}, dep[100001]{};
12+
13+
void dfs(int n, int p, int d) {
14+
par[n][0] = p, dep[n] = d;
15+
for (int i : V[n]) if (i != p) dfs(i, n, d + 1);
16+
}
17+
18+
void makeTable() {
19+
for (int k = 1; k < 17; k++) for (int i = 1; i <= N; i++) par[i][k] = par[par[i][k - 1]][k - 1];
20+
}
21+
22+
pair<int, int> solve(int a, int b) {
23+
int diff = abs(dep[a] - dep[b]);
24+
int ma = 0, mb = 0;
25+
int oa = a, ob = b;
26+
for (int i = 0; i < 17; i++) if (diff & (1 << i)) {
27+
if (dep[a] > dep[b]) a = par[a][i], ma += (1 << i);
28+
else b = par[b][i], mb += (1 << i);
29+
}
30+
31+
while (par[a][0] != par[b][0]) {
32+
for (int i = 16; i >= 0; i--) if (par[a][i] != par[b][i]) {
33+
a = par[a][i], ma += (1 << i);
34+
b = par[b][i], mb += (1 << i);
35+
break;
36+
}
37+
}
38+
if (a != b) {
39+
a = par[a][0], ma++;
40+
b = par[b][0], mb++;
41+
}
42+
43+
int d = ma + mb;
44+
if (ma == mb) return { a, d };
45+
if ((ma + mb) % 2) return { -1,d };
46+
47+
int from = ma > mb ? oa : ob, to = a, len = (ma + mb) / 2;
48+
for (int i = 0; i < 17; i++) if (len & (1 << i)) from = par[from][i];
49+
return { from, d };
50+
51+
}
52+
53+
int main()
54+
{
55+
cin.tie(0)->sync_with_stdio(0);
56+
57+
cin >> N;
58+
for (int i = 1, a, b; i < N; i++) {
59+
cin >> a >> b;
60+
V[a].push_back(b);
61+
V[b].push_back(a);
62+
}
63+
64+
dfs(1, 0, 0);
65+
makeTable();
66+
67+
for (cin >> Q; Q--;) {
68+
int a, b, c;
69+
cin >> a >> b >> c;
70+
int res = -1;
71+
72+
auto[m1, _x] = solve(a, b);
73+
if (m1 != -1) {
74+
auto[_1, l1] = solve(a, m1);
75+
auto[_2, l2] = solve(b, m1);
76+
auto[_3, l3] = solve(c, m1);
77+
if (l1 == l2 && l2 == l3) res = m1;
78+
}
79+
auto[m2, _y] = solve(b, c);
80+
if (m2 != -1) {
81+
auto[_1, l1] = solve(a, m2);
82+
auto[_2, l2] = solve(b, m2);
83+
auto[_3, l3] = solve(c, m2);
84+
if (l1 == l2 && l2 == l3) res = m2;
85+
}
86+
auto[m3, _z] = solve(a, c);
87+
if (m3 != -1) {
88+
auto[_1, l1] = solve(a, m3);
89+
auto[_2, l2] = solve(b, m3);
90+
auto[_3, l3] = solve(c, m3);
91+
if (l1 == l2 && l2 == l3) res = m3;
92+
}
93+
94+
cout << res << '\n';
95+
}
96+
97+
}
98+
99+
```

0 commit comments

Comments
 (0)