Present

Present

Catherine received an array of integers as a gift for March 8. Eventually she grew bored with it, and she started calculated various useless characteristics for it. She succeeded to do it for each one she came up with. But when she came up with another one — xor of all pairwise sums of elements in the array, she realized that she couldn’t compute it for a very large array, thus she asked for your help. Can you do it? Formally, you need to compute

          ( a 1 + a 2 ) ⊕ ( a 1 + a 3 ) ⊕ . . . ⊕ ( a 1 + a n ) ⊕ ( a 2 + a 3 ) ⊕ . . ( a 2 + a n ) ⊕ . . . ⊕ ( a n − 1 ⊕ a n ) (a_1+a_2)⊕(a_1+a_3)⊕...⊕(a_1+a_n)⊕(a_2+a_3)⊕..(a_2+a_n)⊕...⊕(a_{n-1}⊕a_n) (a1+a2)(a1+a3)...(a1+an)(a2+a3)..(a2+an)...(an1an)

Here x⊕y is a bitwise XOR operation (i.e. x ^ y in many modern programming languages).

Input

The first line contains a single integer n ( 2 ≤ n ≤ 400000 ) n (2≤n≤400000) n(2n400000) — the number of integers in the array.

The second line contains integers a 1 , a 2 , … , a n ( 1 ≤ a i ≤ 1 0 7 ) a_1,a_2,…,a_n (1≤ai≤10^7) a1,a2,,an(1ai107).

Output

Print a single integer — xor of all pairwise sums of integers in the given array.

Examples
Input
'2
1 2
Output
3
Input
3
1 2 3
Output
2

Note

In the first sample case there is only one sum 1+2=3.

In the second sample case there are three sums: 1+2=3, 1+3=4, 2+3=5. In binary they are represented as 01 1 2 ⊕ 10 0 2 ⊕ 10 1 2 = 01 0 2 011_2⊕100_2⊕101_2=010_2 011210021012=0102, thus the answer is 2.

思路

题意:给出一个数组,然后按照给出的式子进行异或操作,求出结果。
分析:对于结果的二进制每一位进行判断,如果k位为1,说明有奇数对 ( a i + a j ) (a_i+a_j) (ai+aj)的和k位为1.所以我们就考虑有多少对奇数和的k位为1,即可得出答案。

  1. 首先高于k位的二进制求和对于k位没有影响,所以我们先对 a i a_i ai 2 k + 1 2^{k+1} 2k+1的模,得到 a i a_i ai的范围为 [ 0 , 2 k + 1 − 1 ] [0,2^{k+1}-1] [0,2k+11].
  2. 所以可以得到和的范围为 [ 0 , 2 k + 2 − 2 ] [0,2^{k+2}-2] [0,2k+22],如果k位为1,那么该值范围为 [ 2 k , 2 k + 1 − 1 ] [2^k,2^{k+1}-1] [2k,2k+11] [ 2 k + 2 k + 1 , 2 k + 2 − 2 ] [2^k+2^{k+1},2^{k+2}-2] [2k+2k+1,2k+22].
  3. 所以我们从每一位开始,对于 a i a_i ai进行枚举,二分判断有多少满足的 a j a_j aj即可
代码如下:
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
const int mx=4e5+10;

//2^(k+1)-1       2^(k+2)-2
//[2^i,2^(i+1)-1],[2^(i+1)+2^i,2^(i+2)-2]

int a[mx],b[mx];
int n,ans;

int main()
{
	scanf("%d",&n);
	for(int i=0;i<n;i++)
	scanf("%d",&a[i]);
	
	ans=0;
	for(int k=0;k<26;k++)
	{
		for(int i=0;i<n;i++)
		b[i]=a[i]%(1<<(k+1));//取模
		sort(b,b+n);//排序二分得到答案
		for(int i=0;i<n;i++)
		{
			int L=max(0,(1<<k)-b[i]);//注意max
			int R=(1<<(k+1))-1-b[i];
			int cnt=upper_bound(b,b+i,R)-lower_bound(b,b+i,L);//两个二分得到结果
			if(cnt&1) ans^=1<<k;
			
			L=max(0,(1<<(k+1))+(1<<k)-b[i]);
			R=(1<<(k+2))-1-b[i];
			cnt=upper_bound(b,b+i,R)-lower_bound(b,b+i,L);
			if(cnt&1) ans^=1<<k;
		}
	}
	printf("%d\n",ans);
	return 0;
}	
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值