Codeforces-1323D Present

Codeforces-1323D 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) oplus (a_1 + a_3) oplus ldots oplus (a_1 + a_n) \ oplus (a_2 + a_3) oplus ldots oplus (a_2 + a_n) \ ldots \ oplus (a_{n-1} + a_n) \ ]

Here (x oplus y) is a bitwise XOR operation (i.e. (x) ^ (y) in many modern programming languages). You can read about it in Wikipedia: https://en.wikipedia.org/wiki/Exclusive_or#Bitwise_operation.

Input

The first line contains a single integer (n) ((2 leq n leq 400\,000)) — the number of integers in the array.

The second line contains integers (a_1, a_2, ldots, a_n) ((1 leq a_i leq 10^7)).

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 (011_2 oplus 100_2 oplus 101_2 = 010_2), thus the answer is 2.

(oplus) is the bitwise xor operation. To define (x oplus y), consider binary representations of integers (x) and (y). We put the (i)-th bit of the result to be 1 when exactly one of the (i)-th bits of (x) and (y) is 1. Otherwise, the (i)-th bit of the result is put to be 0. For example, (0101_2 \, oplus \, 0011_2 = 0110_2).

题意

给定n个数,求下式的值

[(a_1 + a_2) oplus (a_1 + a_3) oplus ldots oplus (a_1 + a_n) \ oplus (a_2 + a_3) oplus ldots oplus (a_2 + a_n) \ ldots \ oplus (a_{n-1} + a_n) \ ]

题解

按位考虑贡献,对于每一位,从该位以后截取n个数,将其排序,从1到n枚举每一个数,二分查找剩下的数中相加能对这一位产生贡献的数,能够产生贡献说明两数相加这一位为1,考虑当前枚举到第k位,取模后范围为([0,2^{k+1})),两数相加范围为([0,2^{k+2}-1)),第k位上为1的范围是([2^k,2^{k+1}) ]& [2^{k+1}+2^k, 2^{k+2})),取(2^{k+2}和2^{k+2}-1)做上界并无区别,因为由于取模,第二个范围的r肯定是等于n的,所以可以不写第二个r的二分,直接取n也可.

还要注意自己加自己的情况是不合法的,如果自己加自己也满足第k位上为1,要减去,最后把无序数对/2转化为有序数对数量即可,然后若这一位上1的数量为奇数,则最后异或的结果会产生(1<<k)的贡献

代码

#include <bits/stdc++.h>
using namespace std;
const int N = 4e5 + 50;
int pre[N];
int a[N];
int b[N];
typedef long long ll;
int main() {
    int n;
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
    // ll ans1 = 0;
    // for (int i = 1; i <= n; i++) {
    //     for (int j = i + 1; j <= n; j++) {
    //         ans1 ^= (a[i] + a[j]);
    //     }
    // }
    // printf("%lld
", ans1);
    ll ans = 0;
    for (int i = 0; i < 25; i++) {//逐位考虑每一位上结果是否为1
        int mod = 1 << (i + 1);
        for (int j = 1; j <= n; j++) {//看这一位的影响
            b[j] = a[j] % mod;
        }
        sort(b + 1, b + n + 1);
        ll s = 0;
        for (int j = 1; j <= n; j++) {//枚举两数相加的其中一个数,看两数之和这一位为1的数量
            //取模之后两数相加的范围[ 0, 2^(k+2) )
            int l = lower_bound(b + 1, b + n + 1, (1 << i) - b[j]) - b;//第k位为1的范围1:[ 2^k, 2^(k+1) )
            int r = lower_bound(b + 1, b + n + 1, (1 << (i + 1)) - b[j]) - b - 1;//注意左闭右开
            s += r - l + 1;
            l = lower_bound(b + 1, b + n + 1, (1 << (i + 1)) + (1 << i) - b[j]) - b;//范围2:[ 2^(k+1)+2^k, 2^(k+2) )
            r = lower_bound(b + 1, b + n + 1, (1 << (i + 2)) - b[j]) - b - 1;
            s += r - l + 1;
            if ((b[j] + b[j]) & (1 << i)) s--;//如果自己+自己也符合要求,数量--;
        }
        s /= 2;//无序数对变有序
        if (s & 1) ans += (1 << i);
    }
    printf("%lld
", ans);
    return 0;
}
原文地址:https://www.cnblogs.com/artoriax/p/12577408.html