DOJ logoDOJ
문제
최근 추가된 문제들저장한 문제
카테고리DLC대회그룹팀게시판
랭킹
문제 풀이 랭킹스트릭 랭킹DOJ Power 랭킹
현황
문제 제안로그인회원가입
DOJ logoDOJ

OI 서브태스크 채점, Elo 레이팅, Discord 인증을 갖춘 커뮤니티 온라인 저지.

문제
문제 목록카테고리
커뮤니티
대회랭킹게시판공지사항외부 대회 개최이용 안내
계정
로그인회원가입채점 현황
정책
이용약관DLC 이용 규칙개인정보 처리방침API 사용 설명서언어별 채점 환경대회 순위 보상레이팅과 퍼포먼스
© 2026 DOJ
모든 권리 보유
해설

알록달록한 트리

문제로 돌아가기

해설

정답을 색별로 나누어 생각하자.

고정된 색 ccc에 대해, 모든 정점 vvv는 Tc(v)T_c(v)Tc​(v)라는 값을 가진다. 이 값은 000이거나 색이 ccc인 어떤 정점이다. 색 ccc가 전체 답에 기여하는 값은 같은 TcT_cTc​ 값을 가지는 순서쌍의 개수이므로,

∑xcntc(x)2\sum_x cnt_c(x)^2x∑​cntc​(x)2

이다. 여기서 cntc(x)cnt_c(x)cntc​(x)는 Tc(v)=xT_c(v)=xTc​(v)=x인 정점 의 개수이다. 는 또는 색이 인 정점이다.

이제 각 색에 대해 이 값을 빠르게 계산하면 된다.

색이 ccc인 정점 xxx를 보자. Tc(v)=xT_c(v)=xTc​(v)=x인 정점 vvv는 다음 조건을 만족한다.

  • vvv는 xxx의 서브트리 안에 있다.
  • xxx에서 vvv로 내려가는 경로에서 xxx를 제외하고 색이 ccc인 정점이 없다.

즉, 처음에는 xxx의 서브트리 크기만큼 후보가 있고, 그중 xxx 바로 아래의 같은 색 정점들이 담당하는 서브트리를 빼면 된다.

여기서 ``바로 아래의 같은 색 정점''이란, 색이 ccc인 정점 yyy 중 xxx가 yyy의 가장 가까운 색 ccc 조상인 정점을 뜻한다.

따라서

cntc(x)=subtree(x)−∑subtree(y)cnt_c(x)=subtree(x)-\sum subtree(y)cntc​(x)=subtree(x)−∑s

이다. 합은 xxx가 가장 가까운 같은 색 조상인 정점 yyy들에 대해 취한다.

남은 것은 각 정점 yyy에 대해 가장 가까운 같은 색 조상 sameParent(y)sameParent(y)sameParent(y)를 구하는 것이다. 이는 루트에서 DFS를 하면서 현재 경로 위에서 각 색의 가장 낮은 정점을 저장하면 된다.

DFS로 정점 vvv에 들어갈 때, 현재 last[Cv]last[C_v]last[Cv​]가 vvv의 가장 가까운 같은 색 조상이다. 그 값을 sameParent(v)sameParent(v)에 저장하고, 로 바꾼다. DFS에서 를 빠져나올 때는 원래 값으로 롤백한다. 각 정점마다 한 번씩만 처리하므로 선형 시간이다.

색 ccc에 대해 Tc(v)=0T_c(v)=0Tc​(v)=0인 정점 수도 필요하다. 색 ccc인 정점 중, 같은 색 조상이 없는 정점들을 생각하자. 이 정점들의 서브트리는 서로 겹치지 않고, 그 안에 있는 정점들은 색 ccc 조상을 하나 이상 가진다. 따라서

cntc(0)=N−∑subtree(x)cnt_c(0)=N-\sum subtree(x)cntc​(0)=N−∑subtree(x)

이다. 합은 같은 색 조상이 없는 색 ccc 정점 xxx들에 대해 취한다.

구현에서는 다음 값을 모은다.

  • sameParent(v)=0sameParent(v)=0sameParent(v)=0이면 rootSum[Cv]rootSum[C_v]rootSum[C에 를 더한다.

그 후 정답은

∑c=1K(N−rootSum[c])2+∑v=1N(subtree(v)−sameChildSum[v])2\sum_{c=1}^{K}(N-rootSum[c])^2+ \sum_{v=1}^{N}(subtree(v)-sameChildSum[v])^2c=1∑K​(N

이다.

DFS는 재귀로 구현하면 N=2 000 000N=2\,000\,000N=2000000에서 스택 오버플로가 날 수 있으므로, 반복문 기반 DFS를 사용하는 것이 안전하다.

시간 복잡도는 O(N)O(N)O(N), 메모리 복잡도는 O(N+K)O(N+K)O(N+K)이다.

vvv
xxx
000
ccc
u
b
t
r
ee
(
y
)
sameParent(v)
last[Cv]=vlast[C_v]=vlast[Cv​]=v
vvv
v
​
]
subtree(v)subtree(v)subtree(v)
  • sameParent(v)≠0sameParent(v)\ne 0sameParent(v)=0이면 sameChildSum[sameParent(v)]sameChildSum[sameParent(v)]sameChildSum[sameParent(v)]에 subtree(v)subtree(v)subtree(v)를 더한다.
  • −
    rootSum[c])2+
    v=1∑N​(subtree(v)−
    sameChildSum[v])2