質問の意味:
長さNの配列およびbに
出力((1)+ B( 1)) XOR((1)+ B( 2)) XOR ...((1)+ B (n))をXOR ((2)+ B( 1)) XOR ...((2)+ B (n))はXOR···((N)+ B (n))が値
、すなわち自由に選択された数Aから(I)、B任意数b(j)は、(I選択 ) すべての+のB(j)の組成との排他的論理和
N <= 2e5,0 <= A:データ範囲 (I)において、Bは( I)<= 2 28
アイデア:
暴力は明らかにタイムアウトになりました。
参照XORは、ビットの貢献に考えるのは簡単です
が、ほかは面倒だった、さらにはキャリーを生成すること、また、キャリーをどのように扱うかは非常に良い考えではありません。
私たちは、xビットの位置xよりも明らかに高い、その後、Xの貢献の現在位置を計算すると仮定しますと、1は、影響を与えることはありませんだけで、バイナリビット×1を考慮することです。
セット2 = Tは、xはアレイ及び2TのBモジュロアレイは、Xビットの低い値が得られます。
作るために(I)+ B(J ) x番目のビットは、に必要次の2つの条件のいずれか1である:
T <=(私は)+ B(J ) <2Tは、(x番目のビットのキャリーが発生しませんこの条件は、Xビットが1であり、Xは任意)は、以下のビットで
3T <= A(I)+ B(J)<4T、(結果のXビットが発生し、条件ビットX及びX + 1ビットであります任意の位置x以下の1)
(i)は、それぞれ、2つの2端部は、両方の条件を満足する分離を挙げることができ、間隔の長さは、ビットの数は、数1で、Xは
数値が合計である場合現在の寄与の奇数のビットがお答えします。
PS:
半分は、コードサイズが非常に小さくなりますLOWER_BOUNDができます(私は慣れていません)。
コード:
#include<bits/stdc++.h>
using namespace std;
const int maxm=2e5+5;
int a[maxm];
int b[maxm];
int c[maxm];
int d[maxm];
int n;
int ask(int left,int right){//计算d数组中left<=x<right的x的数量
int st=0,ed=0;
int l=1,r=n;
while(l<=r){//st尽量向左扩展
int mid=(l+r)/2;
if(d[mid]>=left){
st=mid;
r=mid-1;
}else{
l=mid+1;
}
}
l=1,r=n;
while(l<=r){//ed尽量向右扩展
int mid=(l+r)/2;
if(d[mid]<right){
ed=mid;
l=mid+1;
}else{
r=mid-1;
}
}
if(!st||!ed)return 0;//如果不能同时满足x>=left且x<right,则无解
return ed-st+1;
}
signed main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int i=1;i<=n;i++){
cin>>b[i];
}
int ans=0;
for(int i=0;i<30;i++){
int t=(1<<i);
for(int j=1;j<=n;j++){
c[j]=a[j]%(t*2);
d[j]=b[j]%(t*2);
}
sort(c+1,c+1+n);
sort(d+1,d+1+n);
int cnt=0;
for(int j=1;j<=n;j++){//枚举c
cnt+=ask(t-c[j],t*2-c[j]);
cnt+=ask(t*3-c[j],t*4-c[j]);
cnt%=2;
}
if(cnt){
ans+=(1<<i);
}
}
cout<<ans<<endl;
return 0;
}