문제 링크
- http://icpc.me/7610
문제 출처
- 2013 JOI Open Contest 2번
사용 알고리즘
- Link Cut Tree
시간복잡도
- $O((M+Q) \log N)$
풀이
간선 제거 쿼리가 없는 문제를 생각해봅시다.
각 컴포넌트의 “정답”을 루트 정점에 저장하면서, 간선이 추가될 때마다 Union-Find를 이용해 컴포넌트를 합치면 됩니다. 이때 각 컴포넌트의 “정답”은 단순히 컴포넌트의 크기가 됩니다.
간선을 끊는다면? “Link Cut Tree를 쓰면 된다!” 라는 단순하고 명쾌한 해답을 찾을 수 있습니다. Union-Find처럼 각 컴포넌트의 “정답”을 루트 정점에서 관리하면 됩니다.
하지만 간선을 끊는 쿼리와 연결하는 쿼리가 여러 번 주어지면, 두 컴포넌트를 합칠 때 정보의 교집합이 생길 수 있습니다. 이는 트리의 간선이 연결하는 정점 쌍이 바뀌지 않기 때문에 쉽게 처리할 수 있습니다.
간선 $E = (u, v)$가 마지막으로 끊어지기 직전의 컴포넌트 크기 $S(E)$를 알고 있다면, $E$가 다시 트리에 추가될 때 해당 컴포넌트의 “정답”은 $Ans(u)+Ans(v)-S(E)$가 됩니다.
간선을 끊고 붙이고 루트 정점을 구하는 연산은 모두 Link Cut Tree를 이용해 amortized $O(\log N)$에 처리할 수 있습니다.
전체 코드
1 |
|