※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※
이번에 볼 문제는 백준 30050번 문제인 트리와 쿼리
문제는 아래 링크를 확인하자.
https://www.acmicpc.net/problem/30050
1번 연산이 있어도 없어도 (루트 노드를 제외한) 모든 노드의 깊이는 초기상태보다 깊어지지 않음을 관찰하자. 한편 입력으로 주어지는 수는
1번 연산으로 주어지는 각 노드의 새로운 루트를 map 등의 자료구조로 관리해 LCA를 찾아 문제를 해결하자. 1번 연산이 주어진 적이 없다면 그 노드의 부모는 노드번호를 2로 나눈 몫으로 구할 수 있다.
부모노드로 거슬러올라가는 과정에서 노드번호가 항상 감소한다는 점을 이용하면, 두 노드의 번호가 같아질 때까지 번호가 더 큰 노드를 부모 방향으로 거슬러올라가게 하는 것을 반복하는 것으로 두 노드 사이를 잇는 경로를 찾아낼 수 있다.
아래는 제출한 소스코드이다.
#include <iostream>
#include <vector>
#include <map>
using namespace std;
typedef long long ll;
int Q;
map<int, int> mp;
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> Q;
while (Q--) {
int q, x, y; cin >> q >> x >> y;
if (q == 1) {
if (mp.count(y)) mp[y] = x;
else mp.insert(make_pair(y, x));
}
else {
ll ans = x + y;
while (x != y) {
if (x > y) {
if (mp.count(x)) x = mp[x];
else x /= 2;
ans += x;
}
else {
if (mp.count(y)) y = mp[y];
else y /= 2;
ans += y;
}
}
cout << ans - x << '\n';
}
}
}
728x90
'BOJ' 카테고리의 다른 글
[BOJ 1490 // C++] 자리수로 나누기 (1) | 2024.06.08 |
---|---|
[BOJ 20917 // C++] 사회적 거리 두기 (0) | 2024.06.07 |
[BOJ 21278 // C++] 호석이 두 마리 치킨 (0) | 2024.06.05 |
[BOJ 2632 // C++] 피자판매 (0) | 2024.06.04 |
[BOJ 26654 // C++] 원점 (0) | 2024.06.03 |