1.Codeforces Round #626 Div2
D. Present(位运算+二分)
题意:
给一个数组,求(a1+a2)^(a1+a3)^...(a1+an)^(a2+ a3)^...(a2+an)....^(an-1+an)
思路:
可以看出答案中每一位的贡献都是独立的,所以我们计算每一位的贡献
对于第i位,因为i位之后的数对第i位不会产生影响,所以我们分别对a[i]%(1<<(i+1)),取模之后的任意两数和不会超过2i+2-2
还有一个很显而易见的事就是任意两数和第i位上为1的个数如果是奇数的话第i位就会对答案产生贡献,所以我们就只要查找有多少对符合要求的数
如果两数之和在[2i , 2i+1) 与 [2i+1+2i , 2i+2-2] 这两个区间之内,第i位上就会为1
之后就是一个比较经典的二分问题了,就是对于一个数找有多少个符合相加满足一定条件的数的个数,对于每个数二分一下即可
#include<iostream> #include<algorithm> using namespace std; const int maxn=4e5+10; int a[maxn],b[maxn]; int main() { int n,ans=0; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=0;i<=24;i++){ int cnt=0; for(int j=1;j<=n;j++) b[j]=a[j]%(1<<(i+1)); sort(b+1,b+1+n); for(int j=1;j<=n;j++){ int l=lower_bound(b+1,b+1+n,(1<<i)-b[j])-b; l=max(l,j+1); int r=lower_bound(b+1,b+1+n,(1<<(i+1))-b[j])-b; r=max(r,j+1); cnt+=(r-l); } for(int j=1;j<=n;j++){ int l=lower_bound(b+1,b+1+n,(1<<i)+(1<<(i+1))-b[j])-b; l=max(l,j+1); int r=n+1; cnt+=(r-l); } if(cnt%2) ans+=1<<i; } cout<<ans<<endl; return 0; }