出現する整数が高々4000種類しかないので、4000個のcompact bit vectorを持ってすべてのクエリに対して累積和で計算する、みたいなムーブを最初にやってしまった。(部分点は取れる。) 結局、バケット法+bitset高速化をした。
簡単のために、数列aとbの長さは両方Nとする。aとbを長さB毎に区切ってk:=N/B個の区間に分解し、さらにそれぞれの区間に対して長さ4000のビット配列を保持する。このビット配列をα1,...,αk,β1,...,βkとする。それぞれの区間について、出現する整数の奇遇を数えて
αi[x]:={1(整数xが区間内に奇数個ある場合)0(整数xが区間内に偶数個ある場合)
としておく。(βiも同様)
各クエリの指定区間に含まれるバケットαi,βiのXORを取って、端の部分は愚直に数えれば、立っているビットの数が答えになる。出現する値の最大値をAとすると、計算量はO(Q((N/B)⋅(A/logA)+B))。B=Θ(NA/logA)ならO(QNA/logA)。(/logAの部分はいわゆるbitset高速化)
コンテスト中は深く考えずにB=200としたのだけど、計算量を見るとNよりは大きいほうがよさそうだったのでB=1000としてみたら遅くなった。なにか勘違いしてるかも。
tmwilliamlinさんの提出を見たら、単純なbitsetの累積和で処理していた。それはそうだった…… O((N+Q)A/logA)。
Egorさんは出現する整数のほうを下位5ビットごとに分割して、bitsetなしで通している。