BOJ 23091 Calculate! 3

BOJ 23091 Calculate! 3

문제 링크:

문제 내용

정점의 개수가 NN인 트리가 주어집니다. 각 간선의 가중치는 1 이상 30 이하의 정수입니다. 이때 다음의 쿼리를 처리하세요.

  • 1 a b c: 정점 aabb를 연결하는 간선의 가중치를 cc로 바꿉니다. (간선은 존재함이 보장됨; 1c301 \le c \le 30)
  • 2 c: 모든 서로 다른 정점의 쌍 중에서 그 두 정점을 연결하는 경로 상의 가중치들의 XOR이 cc인 경로의 개수를 출력합니다. (1c301 \le c \le 30)

문제 풀이

스포일러

정점 XX와 정점 YY를 잇는 경로 상의 가중치들의 XOR은 루트에서 정점 XX까지의 경로의 XOR과 루트에서 YY까지의 경로의 XOR을 XOR한 것과 같습니다.

따라서, 다음과 같은 방법으로 쿼리를 처리할 수 있습니다.

  • 각 정점의 가중치를 루트에서 그 정점으로의 경로의 XOR로 둡니다.
  • Euler tour segment tree를 만들고, 세그 노드에는 구간 내에서 가중치가 0~31인 정점의 개수를 저장합니다.
  • 간선의 가중치가 바뀌면 서브트리 내의 모든 점의 가중치가 (기존 가중치 XOR 새로운 가중치)를 XOR한 것으로 바뀝니다. 이는 구간에 XOR할 값을 저장하는 레이지로 관리할 수 있습니다.
  • XOR이 cc인 경로의 개수는 전체 트리에서 가중치가 0~31인 정점의 개수를 쿼리한 다음, ii의 개수와 ixorci \operatorname{xor} c의 개수의 곱의 합을 이용하여 구할 수 있습니다.
Last updated on