質問の意味:
長さNの配列の
計算要件((1)+( 2)) XOR((1)+( 3)) XOR ...((1)+ (N)) XOR ((2)+( 3)) XOR ...((2)+ (N)) XOR((3)+( 4))...((N-1)+(nは))。
それは、すべてです「との追加注文」とXORを。
データ範囲:N <= 4e5,1 <= A (I)<= 1E7
アイデア:
元のタイトル(参照することはできません):AtCoder3943二つの配列
基本的には同じ考え。
参照XORは、ビットの貢献に考えるのは簡単です
が、ほかは面倒だった、さらにはキャリーを生成すること、また、キャリーをどのように扱うかは非常に良い考えではありません。
私たちは、xビットの位置xよりも明らかに高い、その後、Xの貢献の現在位置を計算すると仮定しますと、1は、影響を与えることはありませんだけで、バイナリビット×1を考慮することです。
= T 2セットxは、アレイ2Tは下位Xビットが得られる値を法。
(I)+(Jするために ) x番目のビットが1であると、それは次の2つの条件のいずれか取る:
T <=(I)+(J ) <2Tを、(x番目のビットのキャリーが発生しませんこの条件は、Xビットが1であり、Xは任意)は、以下のビットで
3T <= A(I)+ A(J)<4T、(結果のXビットが発生し、条件ビットX及びX + 1ビットであります図1に示すように、任意の位置x以下)
(I)を挙げることができ、それぞれ、2つの2セクションは2つのエンドポイントは、これらの二つの条件を満たしている分離、間隔の長さは、数1つのxビットの数であります
注いくつかのポイントがある:
1区間の長さの和は、疾患の数の和を算出しているため、要求の対象が順序対で、総数は2で除算され
、各Aの2(i)は、低減する必要が自分の状況(:、最初のiが決定される間隔で、第二、自分自身を追加し、最初のビットが1×であるか否かを判断する決意法)と一致します。
数が奇数の場合は最後に、現在位置の寄与の合計が答える場合。
PS:
手書き半分内のコードは、そのコードサイズが非常に大きくなります。
小さな変化量がコードをLOWER_BOUND場合は、コードがたくさん短くなります。
コード:
#include<bits/stdc++.h>
using namespace std;
const int maxm=4e5+5;
int a[maxm];
int b[maxm];
int n;
int ask(int left,int right,int idx){//计算b数组中left<=x<right的x的数量
int st=0,ed=0;
int l=1,r=n;
while(l<=r){//st尽量向左扩展
int mid=(l+r)/2;
if(b[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(b[mid]<right){
ed=mid;
l=mid+1;
}else{
r=mid-1;
}
}
if(!st||!ed)return 0;//如果不能同时满足x>=left且x<right,则无解
int ans=ed-st+1;
if(st<=idx&&ed>=idx)ans--;//自己不能和自己匹配,如果自己在区间内就减1
return ans;
}
signed main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
int ans=0;
for(int i=0;i<25;i++){
int t=(1<<i);
for(int j=1;j<=n;j++){
b[j]=a[j]%(t*2);
}
sort(b+1,b+1+n);
int cnt=0;
for(int j=1;j<=n;j++){
cnt+=ask(t-b[j],t*2-b[j],j);
cnt+=ask(t*3-b[j],t*4-b[j],j);
}
cnt/=2;//因为题目要求的数对是有序对,所以要除以2
if(cnt&1)ans+=(1<<i);
}
printf("%d\n",ans);
return 0;
}