L: XORed Array
全体FA: touhokudai (49:05)�オンサイトFA: touhokudai (49:05)
AC: 9/26
原案: zawatin, writer: amesyu
問題概要
長さNの非負正数列Aが与えられる。�Q回下記の操作を行った後のAを出力せよ。
解法
2kの位が0か1になるのは2k+1の周期がある。���������前半2kは0、後半2kが1になっている。
値 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
K = 0 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 |
K = 1 | 0 | 0 | 1 | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 1 | 1 | 0 | 0 |
K = 2 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 1 | 1 |
K = 3 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 |
解法
値を +1 してみる。���������周期が左にずれた。(循環している)
値 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
K = 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 |
K = 1 | 0 | 1 | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 1 |
K = 2 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 1 | 1 | 1 |
K = 3 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
解法
i = 0, 1, 2 … N の順にAiに作用する寄与を求めていく時、�各ビット毎に2k+1の周期の配列を左に1回シフトを行う。
-> 1シフト行ったことにして1寄与する範囲をずらせばOK!
解法
kビット目におけるxの寄与の位置というのはxを2k+1で割ったあまりで求めることができる。毎回寄与は1回シフトを行うのでi = Lのときに挿入するときは位置をL回左にシフトした位置になることに注意。
�1寄与している範囲に含まれている個数が奇数ならば�A[i] = A[i] xor 2k で更新を行う。
解法
今回の制約ではxi < 2^30であるため k = 30 まで確かめる必要がある。(xi + N - 1)が最大値なのでk = 29 だと足りない(罠)��230+1の配列を作るのは絶望的... ��1. 使われる範囲の個数は少ないので利用する�2. 上位ビットは別の操作で代用する
解法
kが大きい部分は1寄与する範囲が大きいので直接範囲に作用させる。N ≤ 2×105 より 18 ≤ k ならば範囲は一個しかないため、imos法などを用いて範囲の最初に1、最後に1を立てておけばよい。
時間空間ともにO((N + Q)logN) で解けた。