백준 16748 Colorful Tree

 16748번: Colorful Tree (acmicpc.net)




오일러 투어 테크닉을 이용하여, 트리를 선형으로 핀다음, Map을 통해, 한 서브 트리가 가지는 특정 색깔의 갯수를 세그먼트 트리를 통해 O(log N)에 찾을 수 있다.

자바는 시간이 빠듯하여, 바텀업으로 하는 것을 추천한다.
O(N(log N)^2)의 상수를 최대한 줄여야 한다. 여유? 그건 C++

어떤 하나의 색깔이 추가 될 때, 트리를 최적화 하게 만들어 둔다고 했을 때, 추가 하는 색깔의 위치는, 그 전 색깔을 통해 만들어진 최적화 트리를 통해 만들어진 LCA의 서브 트리 아래에 종속되어 있거나, 서브트리에 속하지 않는다.

1. 서브트리 아래에 종속 되어 있을 때

1. 최적화 된 트리 안에 색을 추가하는 경우는 트리의 크기에 변화를 주지 않는다.

2. 최적화 된 트리 바깥에 색을 추가하는 경우는, 서브트리에서 색을 발견 할 때까지 거슬러 올라가, 거리를 더해준다.

2. 서브트리 바깥에 있을 때

1. 특정 노드의 서브트리 안에 색을 발견 할 때 까지 거슬러 올라가 거리를 더해준다.

 그 지점이 색의 LCA를 서브트리로 가지고 있는 다면, LCA와의 거리도 더해준다.


특정 색깔의 LCA는 깊이가 가장 높은 노드부터, 루트 노드까지의 경로 선상에 존재하게 된다.

색깔의 LCA는 그 경로 선상에서 서브 트리가 특정 색깔을 모두 가지고 있는 노드 중, 제일 하위 노드이다. 이런 색깔의 LCA는 루트와 특정 색깔의 최하위 노드의 경로 선상에서 파라매트릭 서치를 하면 된다. 이 경우 파라매트릭을 하며, 세그먼트 트리 쿼리를 날리므로, O(log N) ^ 2 이다.

색을 발견 할 때 까지 거슬러 올라 가는 것도, 루트와의 경로에서, 파라매트릭 서치를 하며, 세그먼트 트리 쿼리를 날리면 된다.


색깔에 대한 트리의 크기 응답에는 O(1)

색깔을 바꾸는 데에는 O(log N ^ 2 )가 소요된다.


색깔을 없애는 방법은 그 위치에 대한 색깔정보를 없애 버리고, 새롭게 추가하려는 시도를 한다. 그 때, 업데이트로 이루어지는 추가되는 트리의 크기가 색깔 제거로 인해 없어져 버리는 트리의 크기와 같다.


색깔의 최하위 노드는 우선순위 큐를 이용하여, 관리한다.

최하위 노드 자체를 저장하는데, 우선순위는 깊이가 높은 순이다.

특정 컬러의 최하위 노드를 저장하는 우선순위 큐에 대해, 최대 100000의 추가 쿼리를 날리게 되고, 컬러에 저장 된 노드의 색깔이 현재 색깔이랑 맞지 않는다면 제거한다. 그럼 최대 50000의 제거를 하게 되고, 대충 O(N log N)이 걸리게 된다.


자세한 증명은 여백이 부족해 생략하도록 하겠다.


트리는 한점을 기준으로 한방향으로 쫘악 펼치면, 분기점이 있는 배열로 볼 수 있다.

숲을 보기보단 나무를 보는 느낌으로 접근하면 쉽게 트리에서 파라매트릭을 할 수 있다.


또한 LCA를 구하는 시간을 줄이기 위해, HLD나, 희소배열을 사용 할 수 있다.

세그먼트 트리 또한 활용해야 한다.


총 시간은 O(N (log N) ^ 2 ) 이 나오게 된다.



이 문제가 왤논이라면서 추천한 친구란놈은 무릎을 꿇도록 하자.

댓글

이 블로그의 인기 게시물

SW - IT 충남대 콘테스트 문제 풀이 + 후기

볼록 껍질 알고리즘