Google Code Jam 2019 Round 1A : Alien Rhyme

問題. Alien Rhyme

英大文字からなる  N 個の単語が与えれる.各単語に任意に1つアクセントを付ける.アクセントから末尾までの部分文字列をその単語のアクセント接尾辞と呼ぶことにする.2つの異なる単語が同じアクセント接尾辞を持つとき,それらの単語は韻を踏んでいるという. N 個の単語からいくつかのペアを作る.ただし,各ペアは韻を踏んでおり,どの単語も複数のペアに含まれていないとする.また,異なるペア間のアクセント接尾辞はどれも異なるものとする.このようなペアを最大でいくつ選ぶことができるかを答えよ.

制約 1 \le N \le 1,000,  1 \le w_i \le 50 w_i i 番目の単語)

解法

接尾辞は各単語の長さが異なるときに扱いにくいので,各単語を逆順にして接頭辞で考える.Trie木を考えると,葉以外の頂点  v に対して, v でアクセントを取るということは,根から  v までの道に対応する文字列がアクセント接頭辞として選ばれたということを意味している.どの異なる2つのペアも同じアクセント接頭辞を取らないということは, v でアクセントを付けてペアとして選ぶことができるのは高々1組ということが分かる.以上の考察から,Tire木の葉の方向からまだ選ばれていない単語を貪欲的にペアにすることによって答えが求まる.
本番ではTrie木を陽に持たずに実装した.ペアの選び方は  \binom{N}{2} 通りあり,各組に対してその最長の接頭辞を求める.そして,解の候補の中で接頭辞が長いペア(どの単語も解に選ばれていないもの)から貪欲的に解の候補として考える.このとき,そのペアの接頭辞が既に選ばれている場合は,接頭辞を1文字づつ短くしてチェックする.この操作は,2つの単語に対応する葉の最長共通祖先から根へアクセントを変更することに対応する.
実際にTrie木を実装した方がより高速に解を求めることができるはず.

計算時間 O(W^2 N^2 \log N) ( W = max_{1 \le i \le N} |w_i|

 
 
Trie木を意識した実装で時間計算量は  O(W N \log N) である.こちらの方が高速で実装もシンプル.

出力のフォーマットをミスってWAを貰ったのが残念.