codefoces 1323D - Present

https://codeforces.com/problemset/problem/1323/D
image

思路

这道题暴力求解的复杂的是\(O(n^2)\)一定不可行,考虑对于二进制的每一位求解。
对于最终答案的每一位,只有两两之和为1的个数达到奇数个,这一位是1,否则是0。
设现在要求答案第i位,那么比i位高的位数没有影响,通过取模(1<<(i+1))去掉。
随后进行排序,这是为了再接下来通过二分统计两两之和为1的个数。
对于取模后,两两之和如果想要是1,取值范围是[ (1<<i), (1<<(i+1)) ) 或者 [ (1<<i)+(1<<(i+1)), (1<<(i+2)) ),通过二分统计出两两之和为1的个数。

代码

点击查看代码
#include <bits/stdc++.h>
using namespace std;

int n;
int a[400005];
int b[400005];

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);

    cin >> n;
    for(int i=1;i<=n;++i)
        cin >> a[i];

    int ans = 0;
    for(int i=0;i<=25;++i)
    {
        int mod = 1 << (i + 1);
        for(int j=1;j<=n;++j)
            b[j] = a[j] % mod;

        sort(b+1,b+1+n);

        int l,r,num = 0;
        for(int j=1;j<=n;++j)
        {
            l = lower_bound(b+1, b+1+n, (1<<i)-b[j]) - b;
            r = lower_bound(b+1, b+1+n, (1<<(i+1))-b[j]) - b;
            num += (r - l);
            l = lower_bound(b+1, b+1+n, (1<<i)+(1<<(i+1))-b[j]) - b;
            r = lower_bound(b+1, b+1+n, (1<<(i+2))-b[j]) - b;
            num += (r - l);
            if((b[j]+b[j])&(1<<i))
                num--;
        }
        if((num/2)&1)
            ans += (1 << i);
    }
    cout << ans << endl;

    return 0;
}


posted @ 2022-07-05 22:35  HIVM  阅读(11)  评论(0编辑  收藏  举报