競技プログラミングのためのF#入門
2^{60}
はint64
の範囲におさまります.
1 2 3 |
|
mod
計算用の演算子定義¶1 2 |
|
たまにはまる場合があるため, a
とb
にも都度%MOD
をかませています.
計算するのは排他的論理和で各ビットごとに計算した結果を積めば十分です. 特に10進表記のa
の各i
ビットは(a>>>i)%2L
で取れます. ビットごとの和が必要なため, ビットでの各i
桁ごとにAa |> Array.sumBy (fun a -> (a>>>i)%2L)
を計算します.
1 2 |
|
解説にあるように各ビットごとの問題のXOR
の総和は0の個数 * 1の個数
です. 最終的には10進数としての和を取る必要があるため, 各i
ごとに2^i
をかける必要があります. この和はfold2
で次のように計算できます.
1 2 3 |
|
本体はi
とy
の計算です. 解説にある0の個数 * 1の個数
をy .* (N-y)
です. 上で書いたように, これに2^i = pown 2L i
をかけています. あとはそこまでの和acc
に積めば総和が計算できます.