ps | |
---|---|
링크 | acmicpc.net/… |
출처 | BOJ |
문제 번호 | 15782 |
문제명 | Calculate! 2 |
레벨 | 플래티넘 3 |
분류 |
구간 쿼리 |
시간복잡도 | O(n+mlogn) |
인풋사이즈 | n<=100,000, m<=500,000 |
사용한 언어 | Python |
제출기록 | 81584KB / 3452ms |
최고기록 | 3452ms |
해결날짜 | 2021/05/06 |
"""Solution code for "BOJ 15782. Calculate! 2".
- Problem link: https://www.acmicpc.net/problem/15782
- Solution link: http://www.teferi.net/ps/problems/boj/15782
"""
import sys
from teflib import fenwicktree
from teflib import tgraph
def euler_tour_technique(tree, root, values):
values_in_dfs_order = []
subtree_ranges = [[None, None] for _ in tree]
for node in tgraph.dfs(tree, root, yields_on_leave=True):
if subtree_ranges[node][0] is None:
subtree_ranges[node][0] = len(values_in_dfs_order)
values_in_dfs_order.append(values[node])
else:
subtree_ranges[node][1] = len(values_in_dfs_order)
return values_in_dfs_order, subtree_ranges
def main():
N, M = [int(x) for x in sys.stdin.readline().split()]
tree = [[] for _ in range(N)]
for _ in range(N - 1):
A, B = [int(x) for x in sys.stdin.readline().split()]
tree[A - 1].append(B - 1)
tree[B - 1].append(A - 1)
nums = [int(x) for x in sys.stdin.readline().split()]
nums_in_dfs_order, subtree_ranges = euler_tour_technique(tree, 0, nums)
fenwick1 = fenwicktree.XorFenwickTree(N + 1)
fenwick2 = fenwicktree.XorFenwickTree(nums_in_dfs_order + [0])
for _ in range(M):
query = [int(x) for x in sys.stdin.readline().split()]
if query[0] == 1:
x = query[1]
beg, end = subtree_ranges[x - 1]
res = fenwick2.query(0, end) ^ fenwick2.query(0, beg)
if not beg % 2:
res ^= fenwick1.query(0, beg)
if not end % 2:
res ^= fenwick1.query(0, end)
print(res)
else:
x, y = query[1:]
beg, end = subtree_ranges[x - 1]
fenwick1.update(beg, y)
fenwick1.update(end, y)
if not beg % 2:
fenwick2.update(beg, y)
if not end % 2:
fenwick2.update(end, y)
if __name__ == '__main__':
main()