BOJ 31480 양갈래 바이러스

BOJ 31480 양갈래 바이러스

문제 링크:

문제 내용

정점의 개수가 NN인 포화 이진 트리가 있습니다. 정점 i>1i > 1은 정점 i2\lfloor \frac{i}{2} \rfloor를 부모로 갖습니다.

각 정점의 현재 값은 모두 0입니다. 다음의 쿼리가 QQ개 주어질 때, 모든 쿼리가 종료된 후의 각 정점의 값을 출력하세요.

  • v p d: 정점 vv에서 거리 dd 이하인 모든 정점에 pp를 더합니다. 두 정점 aabb의 거리는 정점 aa에서 정점 bb로 가기 위해 거쳐야 하는 간선의 최소 개수로 정의합니다.

입력

첫 줄에 NNQQ가 주어집니다. (1N<2181 \le N < 2^{18}, 1Q200  0001 \le Q \le 200\;000)

다음 QQ개 줄에는 각 쿼리의 정보가 주어집니다. (1vN1 \le v \le N, 1p10001 \le p \le 1000, 0d2(log2(N+1)1)0 \le d \le 2(\log_2 (N+1) - 1))

출력

1번부터 NN번 정점까지 순서대로 각 정점의 값을 한 줄에 공백으로 구분하여 출력합니다.

문제 풀이

스포일러

이 문제는 여러가지 풀이가 있습니다. 여기서는 차분 배열을 이용한 풀이를 소개합니다.

정점 ii에서 거리 dd인 정점은 ii의 부모 정점 방향과 자식 정점 방향으로 나눠집니다. 그 중 자식 정점 방향에 있는 정점들의 모임은 각 층별로 하나의 구간을 이루며, dd 또는 ii로부터의 최장거리 만큼의 구간이 만들어집니다.

부모 정점 방향의 경우, 그 부모에서 다른 자식으로 이동하면 같은 방법으로 서브트리를 처리할 수 있고, 거기서 다시 부모로 이동하면 루트에 닿거나 남은 거리가 0이 될 때까지 반복됩니다. 이렇게 만들어지는 구간의 총 개수는 O(log2N)\mathcal{O} (\log^2 N)개입니다.

모든 쿼리가 끝난 후의 답만 중요하므로, 차분 배열을 써서 각각의 구간 업데이트를 O(1)\mathcal{O}(1) 시간에 할 수 있고, 따라서 총 소요 시간은 O(Qlog2N)\mathcal{O}(Q \log^2 N)이 됩니다.

Last updated on