<span>[Codeforces Round #626 (Div. 2, based on Moscow Open Olympiad in Informatics)] -D. Present(异或性质,按位拆分,树桩数组)</span>

[Codeforces Round #626 (Div. 2, based on Moscow Open Olympiad in Informatics)] -D. Present(异或性质,按位拆分,树桩数组)

D. Present

time limit per test

3 seconds

memory limit per test

512 megabytes

input

standard input

output

standard output

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

(a1+a2)⊕(a1+a3)⊕…⊕(a1+an)⊕(a2+a3)⊕…⊕(a2+an)…⊕(an−1+an)(a1+a2)⊕(a1+a3)⊕…⊕(a1+an)⊕(a2+a3)⊕…⊕(a2+an)…⊕(an−1+an)

Here x⊕yx⊕y is a bitwise XOR operation (i.e. xx ^ yy 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 nn (2≤n≤4000002≤n≤400000) — the number of integers in the array.

The second line contains integers a1,a2,…,ana1,a2,…,an (1≤ai≤1071≤ai≤107).

Output

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

Examples

input

Copy

2
1 2

output

Copy

3

input

Copy

3
1 2 3

output

Copy

2

Note

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

In the second sample case there are three sums: 1+2=31+2=3, 1+3=41+3=4, 2+3=52+3=5. In binary they are represented as 0112⊕1002⊕1012=01020112⊕1002⊕1012=0102, thus the answer is 2.

⊕⊕ is the bitwise xor operation. To define x⊕yx⊕y, consider binary representations of integers xx and yy. We put the ii-th bit of the result to be 1 when exactly one of the ii-th bits of xx and yy is 1. Otherwise, the ii-th bit of the result is put to be 0. For example, 01012⊕00112=0110201012⊕00112=01102.

题意:

给定一个含有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) \\\)

思路:

我们知道异或是不作进位的加法,所以我们考虑计算答案的每一位,从而得出答案值。

对于第\(\mathit k\)位(从第0位开始),我们考虑将所有的\(a_i\)\(2^{k+1}\)取模后有多少对\((i,j)\)使其\(sum=a_i+a_j\)的第\(\mathit k\)位为1,

我们知道在取模操作后第k位为1的话,sum要在\([2^k, 2^{k+1}),[2^{k+1} + 2^k, 2^{k+2} - 2]\) 这2个区间中。

可以将取模后的数字取模后用转指针或者二分法来求点对的个数,

这里我用的是树状数组记录数值出现的次数来求得,时间复杂度和空间复杂度都不优,仅做一种可行写法示例。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <iomanip>
#include <sstream>
#include <bitset>
#define ALL(x) (x).begin(), (x).end()
#define sz(a) int(a.size())
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define pii pair<int,int>
#define pll pair<long long ,long long>
#define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define MS0(X) memset((X), 0, sizeof((X)))
#define MSC0(X) memset((X), '\0', sizeof((X)))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define eps 1e-6
#define chu(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
#define du3(a,b,c) scanf("%d %d %d",&(a),&(b),&(c))
#define du2(a,b) scanf("%d %d",&(a),&(b))
#define du1(a) scanf("%d",&(a));
using namespace std;
typedef long long ll;
ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
ll powmod(ll a, ll b, ll MOD) { if (a == 0ll) {return 0ll;} a %= MOD; ll ans = 1; while (b) {if (b & 1) {ans = ans * a % MOD;} a = a * a % MOD; b >>= 1;} return ans;}
ll poww(ll a, ll b) { if (a == 0ll) {return 0ll;} ll ans = 1; while (b) {if (b & 1) {ans = ans * a ;} a = a * a ; b >>= 1;} return ans;}
void Pv(const vector<int> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%d", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("\n");}}}
void Pvl(const vector<ll> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%lld", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("\n");}}}
inline long long readll() {long long tmp = 0, fh = 1; char c = getchar(); while (c < '0' || c > '9') {if (c == '-') fh = -1; c = getchar();} while (c >= '0' && c <= '9') tmp = tmp * 10 + c - 48, c = getchar(); return tmp * fh;}
inline int readint() {int tmp = 0, fh = 1; char c = getchar(); while (c < '0' || c > '9') {if (c == '-') fh = -1; c = getchar();} while (c >= '0' && c <= '9') tmp = tmp * 10 + c - 48, c = getchar(); return tmp * fh;}
const int maxn = 100000100;
const int inf = 0x3f3f3f3f;
/*** TEMPLATE CODE * * STARTS HERE ***/
int tree[maxn];
int lowbit(int x)
{
    return (-x)& x;
}
void add(int pos, int val)
{
    pos++;
    while (pos < maxn)
    {
        tree[pos] += val;
        pos += lowbit(pos);
    }
}
int ask(int pos)
{
    pos++;
    int res = 0;
    while (pos > 0)
    {
        res += tree[pos];
        pos -= lowbit(pos);
    }
    return res;
}

int n;
int a[400010];
int query(int l, int r)
{
    return ask(r) - ask(l - 1);
}
int main()
{
    //freopen("D:\\code\\text\\input.txt","r",stdin);
    //freopen("D:\\code\\text\\output.txt","w",stdout);
    n = readint();
    repd(i, 1, n)
    {
        a[i] = readint();
    }
    ll ans = 0ll;
    for (int i = 0; i <= 24; ++i)
    {
        ll res = 0ll;
        repd(j, 1, n)
        {
            int x = a[j] % (1 << i + 1);
            res += query((1 << i) - x, (1 << i + 1) - 1 - x);
            res += query((1 << i) + (1 << i + 1) - x, (1 << i + 2) - 2 - x);
            add(x, 1);
        }
        repd(j, 1, n)
        {
            int x = a[j] % (1 << i + 1);
            add(x, -1);
        }
        if (res & 1)
        {
            ans += (1 << i);
        }
    }
    printf("%lld\n", ans );
    return 0;
}



全部评论

相关推荐

不愿透露姓名的神秘牛友
06-19 14:46
和女友两个人马上毕业,现在我在鹅实习995,周六日偶尔也去北京;她在北京金融007,经常忙到后半夜,周末也没啥休息机会两个人现在都不咋聊天了,一句话隔半小时甚至半天才回。&nbsp;她是个很优秀的妹子,工作也很努力,是值得学习一辈子的人。我在努力工作求转正,即便不行至少赚到了一段不错的实习经历。已经异地了半年,接下来可能还会持续是这个状态。我们都算是对方重要的人,只是感觉看上去不是很有未来的样子。希望牛友们给点的鼓励
梦旅奇缘:很难。异地首先就已经很难了,加上妹子是金融行业,忙碌高压,对情感需求很高,而且见惯纸醉金迷,你的很多优势在她那里可能就不算什么了。这种情况下,在她们那里遇到一个能及时照顾她的人,即使那人可能很多条件不如你,你也有可能被分手。 说白了,两个卷王就不太适合在一起。因为卷王最大的优势,在另一个卷王那里就不算优势了。
点赞 评论 收藏
分享
头顶尖尖的程序员:我是26届的不太懂,25届不应该是找的正式工作吗?为什么还在找实习?大四还实习的话是为了能转正的的岗位吗
点赞 评论 收藏
分享
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务