====== 트리 ======
===== 풀이 =====
* [[ps:동적 연결성#트리에서의 동적 연결성]] 문제이다. 엣지를 삭제하는 쿼리만 주어지고, 오프라인 쿼리로는 해결할 수 없는 문제이다.
* [[ps:동적 연결성#트리에서의 동적 연결성]]에서 설명했듯이 여러가지 풀이가 가능하다. 자세한 내용은 링크 참조
* 각 풀이를 구현해서 적용한 결과, 걸린 시간은 다음과 같았다.
* [코드 1] 경로 업데이트(HLD) + Fenwick tree : 5832ms
* [코드 2] 서브트리 업데이트(Euler Tour Technique) + Lazy segment tree : 시간 초과. (PyPy로는 2536ms)
* [코드 3] 서브트리 업데이트(Euler Tour Technique) + Xor Fenwick tree : 3364ms
* [코드 생략] DFS로 업데이트 : 시간 초과 (PyPy로도 시간 초과)
* [코드 3] 방법이 시간 복잡도도 O(n+qlogn)으로 가장 빠르고, 실제 수행시간도 가장 빨랐다.
===== 코드 =====
==== 코드 1 ====
"""Solution code for "BOJ 13309. 트리".
- Problem link: https://www.acmicpc.net/problem/13309
- Solution link: http://www.teferi.net/ps/problems/boj/13309
"""
import sys
from teflib import fenwicktree
from teflib import ttree
def main():
N, Q = [int(x) for x in sys.stdin.readline().split()]
tree = [[] for _ in range(N)]
for i in range(1, N):
a = int(sys.stdin.readline())
tree[a - 1].append(i)
tree[i].append(a - 1)
hld = ttree.HeavyLightDecomposition(tree, root=0)
fenwick = fenwicktree.FenwickTree(N)
for i in range(Q):
b, c, d = [int(x) for x in sys.stdin.readline().split()]
ranges = hld.get_ranges_in_path(b - 1, c - 1,
should_include_top_node=False)
is_connected = all(fenwick.query(*r) == 0 for r in ranges)
print('YES' if is_connected else 'NO')
if d == 0:
continue
u = (b - 1) if is_connected else (c - 1)
fenwick.set(hld.get_pos(u), 1)
if __name__ == '__main__':
main()
* Dependency
* [[:ps:teflib:fenwicktree#FenwickTree|teflib.fenwicktree.FenwickTree]]
* [[:ps:teflib:ttree#HeavyLightDecomposition|teflib.ttree.HeavyLightDecomposition]]
==== 코드 2 ====
"""Solution code for "BOJ 13309. 트리".
- Problem link: https://www.acmicpc.net/problem/13309
- Solution link: http://www.teferi.net/ps/problems/boj/13309
"""
import sys
from teflib import segmenttree
from teflib import ttree
def main():
N, Q = [int(x) for x in sys.stdin.readline().split()]
tree = [[] for _ in range(N)]
for i in range(1, N):
a = int(sys.stdin.readline())
tree[a - 1].append(i)
subtree_ranges = ttree.euler_tour_technique(tree, 0)
segtree = segmenttree.LazySegmentTree(
[0] * N,
merge=lambda l, r: 0,
update_value=lambda v, p, size: max(v, p),
update_param=max)
for i in range(Q):
b, c, d = [int(x) for x in sys.stdin.readline().split()]
b_pos = subtree_ranges[b - 1][0]
c_pos = subtree_ranges[c - 1][0]
is_connected = (segtree.get(b_pos) == segtree.get(c_pos))
print('YES' if is_connected else 'NO')
if d == 1:
if is_connected:
segtree.range_update(*subtree_ranges[b - 1], b_pos)
else:
segtree.range_update(*subtree_ranges[c - 1], c_pos)
if __name__ == '__main__':
main()
* Dependency
* [[:ps:teflib:segmenttree#LazySegmentTree|teflib.segmenttree.LazySegmentTree]]
* [[:ps:teflib:ttree#euler_tour_techinique|teflib.ttree.euler_tour_techinique]]
==== 코드 3 ====
"""Solution code for "BOJ 13309. 트리".
- Problem link: https://www.acmicpc.net/problem/13309
- Solution link: http://www.teferi.net/ps/problems/boj/13309
"""
import random
import sys
from teflib import fenwicktree
from teflib import ttree
def main():
N, Q = [int(x) for x in sys.stdin.readline().split()]
tree = [[] for _ in range(N)]
for i in range(1, N):
a = int(sys.stdin.readline())
tree[a - 1].append(i)
subtree_ranges = ttree.euler_tour_technique(tree, root=0)
fenwick = fenwicktree.XorFenwickTree(N + 1)
for i in range(Q):
b, c, d = [int(x) for x in sys.stdin.readline().split()]
b_group = fenwick.query(0, subtree_ranges[b - 1][0] + 1)
c_group = fenwick.query(0, subtree_ranges[c - 1][0] + 1)
is_connected = (b_group == c_group)
print('YES' if is_connected else 'NO')
if d == 1:
update_val = random.getrandbits(32)
if is_connected:
fenwick.update(subtree_ranges[b - 1][0], update_val)
fenwick.update(subtree_ranges[b - 1][1], update_val)
else:
fenwick.update(subtree_ranges[c - 1][0], update_val)
fenwick.update(subtree_ranges[c - 1][1], update_val)
if __name__ == '__main__':
main()
* Dependency
* [[:ps:teflib:fenwicktree#XorFenwickTree|teflib.fenwicktree.XorFenwickTree]]
* [[:ps:teflib:ttree#euler_tour_techinique|teflib.ttree.euler_tour_techinique]]
{{tag>BOJ ps:problems:boj:플래티넘_1}}