2019年10月30日水曜日

ARC 024 C - だれじゃ

ARC 024 C - だれじゃ

「(部分列に)文字ccがちょうどxx個含まれること」の26N26N通りすべてに対して、あらかじめ乱数Rc,xR_{c, x}を割り振っておく。 最初のKK文字のヒストグラムを作って、各文字ccについて該当するRc,xR_{c, x}のXORを取って、最初のハッシュ値とする。

あとは、長さKKの部分列をスライドさせながら各部分列のハッシュ値を求めていく。直前の部分列のハッシュ値がVVであったとし、文字ccが加わってccの数がxxからx+1x+1に増え、文字ddが除かれてddの数がyyからy1y-1に減るとすると、新しい部分列のハッシュ値はVRc,xRc,x+1Rd,yRd,y1V \oplus R_{c, x} \oplus R_{c, x+1} \oplus R_{d, y} \oplus R_{d, y-1}になる。このハッシュ値をキーとして、部分列の開始位置を保持しておく。同じハッシュ値が再び出現した時、開始位置がKK以上離れていればアナグラムダジャレが見つかったことになる。

アルファベットのサイズをα\alphaとするとき、計算量はO(αN){\mathcal O}(\alpha N)


こんなことしなくても、普通にヒストグラムをキーにするだけで通った……