problem
https://arc092.contest.atcoder.jp/tasks/arc092_b
题意
给你两个序列a,b 各n个数
共n^2对数 求这些对的和 之间异或的值
n 200000
a,b里数1<<28
思路
对于最后的结果
考虑每一位 pair的贡献 发现 对于一个a[i] , a[i]+b[j]对于当前位的影响是有规律的 即使其为1的区间为:
a[i]+b[j] ∈ [v,2v) [ v , 2 v ) 和 [3v,n) [ 3 v , n ) 而更高位对当前位永远不会影响
对于每一位 枚举a 二分b求解两个范围的边界即可
时间复杂度 O(28∗n∗logn) O ( 28 ∗ n ∗ l o g n )
代码示例
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+10;
int a[maxn];
int b[maxn];
int n;
int main()
{
//ios::sync_with_stdio(false);
//freopen("in.txt","r",stdin);
scanf("%d",&n);
for(int i=0;i<n;++i) scanf("%d",&a[i]);
for(int i=0;i<n;++i) scanf("%d",&b[i]);
int ans=0;
for(int v=(1<<28);v;v>>=1){
int tp=0;
for(int i=0;i<n;++i){
a[i]&=((v<<1)-1);
b[i]&=((v<<1)-1);
}
sort(a,a+n);
sort(b,b+n);
for(int i=n-1;i>=0;--i){//枚举a
int v1=lower_bound(b,b+n,v-a[i])-b;
int v2=lower_bound(b,b+n,2*v-a[i])-b;
int v3=lower_bound(b,b+n,3*v-a[i])-b;
// while(j<n && a[i]+b[j]<v) j++;
// while(k<n && a[i]+b[k]<2*v) k++;
// while(l<n && a[i]+b[l]<3*v) l++;
tp+=v2-v1+n-v3;
tp&=1;
}
if(tp) ans|=v;
}
printf("%d\n",ans);
return 0;
}