公式

E - Sort Arrays 解説 by toam


\(A_1, A_2, \ldots,A_N\) を辞書順に並べ替えよという問題で,Trie (トライ木)を使って解けます.

\(A_1, \ldots, A_N\) をキーとした Trie を作ります.ただし,同じ数列は同じ Trie のノードに対応するようにします.親ノード \(v\) から値 \(x_i\) の子ノードがすでにあればそれを再利用し,なければ新しいノード \(u\) を作って辺 \(v\stackrel{x_i}{\longrightarrow} u\) を追加するようにします.子ノードの情報は連想配列(C++ の map,Python の dict)などで管理します.また,各ノードにはどの数列が対応するかも記録しておきます.

この Trie 上で DFS をすれば答えが求まります.あるノードから複数の辺が出る場合には,辺の値が小さい順に潜るようにすればよいです.DFS でノードにたどり着いたら,そのノードに対応する数列の添え字を答えの配列に昇順で追加します.

import sys

sys.setrecursionlimit(300100)

n = int(input())
G = [{} for i in range(n + 1)]
vs = [[] for i in range(n + 1)]
pos = [-1] * (n + 1) # 数列 A_i がどのノードに属しているか
pos[0] = 0
tmp = 1
for i in range(1, n + 1):
    p, y = map(int, input().split())
    if y not in G[pos[p]]:
        G[pos[p]][y] = tmp
        tmp += 1
    pos[i] = G[pos[p]][y]
    vs[pos[i]].append(i)

ans = []


def dfs(i):
    global ans
    ans += vs[i]
    for j in sorted(list(G[i].keys())):
        dfs(G[i][j])


dfs(0)
print(*ans)

投稿日時:
最終更新: