Educational Codeforces Round 12 E. Beautiful Subarrays
http://codeforces.com/contest/665/problem/E
問題概要
数列 A が与えられる。連続する部分列のうち全体を xor したものが K 以上であるようなもの個数を数えよ。
解法
A[L..R] を xor したものを S[L..R] と書くことにすると S[L..R] = S[1..R] xor S[1..L-1] が成り立つ。
ここで S[1..L] を S[L] と再定義すれば、この問題は S[i] xor S[j]≧K となる (i,j) の個数を数える問題になる。
さて S[i] xor S[j]≧K を高速に判定するにはどうすればいいだろうか。i を固定して考えてみよう。
K=000011101110, Si=000101001010 を例に挙げる。
Sj が 1... の形なら確実に K 以上になる。
K= 000011101110 Si= 000101001010 Sj= 1...........
Sj が 01... の形なら確実に K 以上になる。
K= 000011101110 Si= 000101001010 Sj= 01..........
Sj が 001... の形なら確実に K 以上になる。
K= 000011101110 Si= 000101001010 Sj= 001.........
Sj が 0000... の形なら確実に K 以上になる。
K= 000011101110 Si= 000101001010 Sj= 0000........
Sj が 00010... の形なら確実に K 未満になる。
K= 000011101110 Si= 000101001010 Sj= 00010.......
Sj が 000111... の形なら確実に K 未満になる。
K= 000011101110 Si= 000101001010 Sj= 000111......
この作業を見ればわかるように、K 以上(未満)が確定したら探索を中止するようにすれば探索ノード数が高々 30 個程度になる。
接頭辞が s であるようなビット列の個数を管理するのは Trie 木が使える。
Educational Codeforces Round 12 E. Beautiful Subar ...
上から見ていけば大小比較ができることには気がついていたが、xor を二回取ると 0 になるという基本的なことに気付けなかった。