SlideShare a Scribd company logo
1 of 24
E : DISTINCT
DICTIONARY
作問:さて
問題概要
初め空の辞書に対し次の3種類のクエリが来ます。
1. 文字列Sidを辞書に追加する。
2. 文字列Sidを辞書から削除する。
3. 辞書に追加された文字列の中である文字列Sidと接頭辞が一致
しているような文字列の中で辞書順最小のものを出力する。
(例: aaabcx
abcdef
aaabdef
が辞書にあった場合に、Sid = “aaa”のとき、
aaabcxのidを出力する。 )
問題概要
1 <= 文字列の数 <= 10^5
1 <= 文字列の長さの合計 <= 10^6
1 <= クエリの数 <= 10^5
想定誤解法
愚直に線型探索
O((文字列の長さの合計)Q)
文字列が接頭辞と一致しているかのチェックを
そのままやってしまうと間に合わない。
想定解法1
Trie木 + SegmentTree O ( Q log M + N log M )
( M = 文字列の長さの総和 )
a
a
a b c
d
b c
与えられる文字列
• aaa
• aaabc
• aabc
• aaad
想定解法1
与えられた文字列を予めソート
a
a
a b c
d
b c
与えられる文字列
1. aaa
2. aaabc
3. aaad
4. aabc
想定解法1
DFS順序で各ノードのindexを割り振る。
0
a,1
a,2
a,3 b,4 c,5
d,6
b,7 c,8
与えられる文字列
1. aaa
2. aaabc
3. aaad
4. aabc
想定解法1
この添字に対応するようにセグメントツリーを構築。
INFで初期化。
0
a,1
a,2
a,3 b,4 c,5
d,6
b,7 c,8
INF
INF
INF
INF
INF INF
INF
INF INF
与えられる文字列
1. aaa
2. aaabc
3. aaad
4. aabc
想定解法1
この添字に対応するようにセグメントツリーを構築。
INFで初期化。
0
a,1
a,2
a,3 b,4 c,5
d,6
b,7 c,8
INF
INF
INF
INF
INF INF
INF
INF INF
与えられる文字列
1. aaa
2. aaabc
3. aaad
4. aabc
想定解法1
1.文字列”aaabc”追加の処理
0
a,1
a,2
a,3 b,4 c,5
d,6
b,7 c,8
INF
INF
INF
INF
INF INF
INF
INF INF
与えられる文字列
1. aaa
2. aaabc
3. aaad
4. aabc
想定解法1
1.文字列”aaabc”追加の処理
末尾のノードのindexを辞書順で
何番目かで更新
0
a,1
a,2
a,3 b,4 c,5
d,6
b,7 c,8
INF
INF
INF
INF
INF 2
INF
INF INF
与えられる文字列
1. aaa
2. aaabc
3. aaad
4. aabc
想定解法1
1.文字列”aaad”を追加
0
a,1
a,2
a,3 b,4 c,5
d,6
b,7 c,8
INF
INF
INF
INF
INF 2
INF
INF INF
与えられる文字列
1. aaa
2. aaabc
3. aaad
4. aabc
想定解法1
1.文字列”aaad”を追加
0
a,1
a,2
a,3 b,4 c,5
d,6
b,7 c,8
INF
INF
INF
INF
INF 2
3
INF INF
与えられる文字列
1. aaa
2. aaabc
3. aaad
4. aabc
想定解法1
3.文字列”aaa”で検索
0
a,1
a,2
a,3 b,4 c,5
d,6
b,7 c,8
INF
INF
INF
INF
INF 2
3
INF INF
与えられる文字列
1. aaa
2. aaabc
3. aaad
4. aabc
想定解法1
3.文字列”aaa”で検索
文字列の末尾のノードが持つ子の中でRMQを使って最小の値を探す。
閉区間
[ 末尾のノードのindex , 末尾のノードが持つ子の最大のinedx ]
0
a,1
a,2
a,3 b,4 c,5
d,6
b,7 c,8
INF
INF
INF
INF
INF 2
3
INF INF
与えられる文字列
1. aaa
2. aaabc
3. aaad
4. aabc
想定解法1
3.文字列”aaa”で検索
文字列の末尾のノードが持つ子の中でRMQを使って最小の値を探す。
辞書順で2番目の値”aaabc”のidを出力。
0
a,1
a,2
a,3 b,4 c,5
d,6
b,7 c,8
INF
INF
INF
INF
INF 2
3
INF INF
与えられる文字列
1. aaa
2. aaabc
3. aaad
4. aabc
想定解法1
2.文字列”aaabc”を削除
0
a,1
a,2
a,3 b,4 c,5
d,6
b,7 c,8
INF
INF
INF
INF
INF 2
3
INF INF
与えられる文字列
1. aaa
2. aaabc
3. aaad
4. aabc
想定解法1
2.文字列”aaabc”を削除
文字列の末尾のノードのindexの要素をINFに戻す。
0
a,1
a,2
a,3 b,4 c,5
d,6
b,7 c,8
INF
INF
INF
INF
INF INF
3
INF INF
与えられる文字列
1. aaa
2. aaabc
3. aaad
4. aabc
想定解法1
3.文字列”aaa”で検索
文字列の末尾のノードが持つ子の中でRMQを使って最小の値を探す。
0
a,1
a,2
a,3 b,4 c,5
d,6
b,7 c,8
INF
INF
INF
INF
INF INF
3
INF INF
与えられる文字列
1. aaa
2. aaabc
3. aaad
4. aabc
想定解法1
3.文字列”aaa”で検索
文字列の末尾のノードが持つ子の中でRMQを使って最小の値を探す。
辞書順で3番目の値”aaad”のidを出力。
0
a,1
a,2
a,3 b,4 c,5
d,6
b,7 c,8
INF
INF
INF
INF
INF INF
3
INF INF
与えられる文字列
1. aaa
2. aaabc
3. aaad
4. aabc
想定解法2
すべての接頭辞のハッシュ値をあらかじめ計算して、
文字列Aの接頭辞が文字列Bであるかどうかを
ハッシュ値の比較でO(1)ですませる。
O( Q log N )
ローリングハッシュ + set
その他の解法
入力の各文字列をsiとし、ti = si + (他の文字より大きい文字)とする。
siとtiの和集合をソートすると、
siを接頭辞として持つすべての文字列は
si-ti間の文字列と一致する。
O ( Q log N + N log M ) くらい?
賢いこと + set
講評
想定難易度:★★★
あとあとになって頭いい楽な解法がたくさん出てきて
よく分からない難易度になった。
全体FA: nwin (01: 00)
On-site FA: Almost_Retired ( 01:36 )
AC / All = 17 / 71 ( 23.94 % )
ジャッジ解
山下 139 行
千田 280 行
大桃1 58 行
大桃2 51 行

More Related Content

More from NariyoshiChida

More from NariyoshiChida (6)

RUPC2015Day2 - A
RUPC2015Day2 - ARUPC2015Day2 - A
RUPC2015Day2 - A
 
RUPC2015Day2 - B
RUPC2015Day2 - BRUPC2015Day2 - B
RUPC2015Day2 - B
 
RUPC2015Day2 - H
RUPC2015Day2 - HRUPC2015Day2 - H
RUPC2015Day2 - H
 
RUPC2015Day2 - 総評
RUPC2015Day2 - 総評RUPC2015Day2 - 総評
RUPC2015Day2 - 総評
 
RUPC2015Day2 - J
RUPC2015Day2 - JRUPC2015Day2 - J
RUPC2015Day2 - J
 
RUPC2015Day2 - G
RUPC2015Day2 - GRUPC2015Day2 - G
RUPC2015Day2 - G
 

RUPC2015Day2 - E