2020年10月12日月曜日

CodeChef October Challenge 2020 - Compress all Subsegments

区間IIに関するffの値は、(Ai)iI(A_i)_{i \in I}中のhighest set bitの位置をkkとして、kkが立っている数が(Ai)iI(A_i)_{i \in I}に何個含まれるかでだいたい決まる:

  1. kkが立っている数が1個でそれ以外が0個の場合、その数自身になる
  2. kkが立っている数が奇数個の場合、上の場合を除いて2k2^kになる
  3. kkが立っている数が2個でそれ以外が0個の場合、不定
  4. kkが立っている数が2個でそれ以外が1個の場合、不定
  5. kkが立っている数が2個でそれ以外が2個以上の場合、0にできる
  6. kkが立っている数が4個でそれ以外が00個の場合、不定
  7. kkが立っている数が4個でそれ以外が11個以上の場合、0にできる
  8. kkが立っている数が6個以上の偶数の場合、それ以外が何個でも0にできる

まずは、kkが立っている数が偶数個の時に常はffの値が0になり、kkが立っている数が奇数個の時は常に2k2^kになるとして、偶奇のみに注目して計算する。そして、後から3, 4, 6のパターンを別に数えて補正する。

前半パートは、i=1,2,...,Ni = 1, 2, ..., Nについてそれぞれ区間[1,i],[2,i],...,[i,i][1, i], [2, i], ..., [i, i]に関する結果の和を求めるとよい。この際、

  • odd[x]:=\operatorname{odd}[x] := highest set bitがxxで、xxが立っている数を奇数個含むような区間の数
  • even[x]:=\operatorname{even}[x] := highest set bitがxxで、xxが立っている数を偶数個含むような区間の数

を保持しながら走査するとまとめて計算できる。O(NlogmaxAi){O}(N\log \max A_i)