Codeforces 1323 D. Present (思维)

 

 题解:

 若答案中的第i位为1,有奇数对j,k使得(a[j]+a[k])的i位为1。a[j]第i+1位及以上对第i位无影响,所以保留前i位为b[j],b[j]+b[k]在[2^i,2^(i+1)-1]U[2^(i+2)-1,2^(i+1)+2^i]均符合,排序b,枚举j,二分查找

[2^i,2^(i+1)-1-b[j]]U[2^(i+2)-1,2^(i+1)+2^i-b[j]]的个数,若b[j]+b[j]第i位为1,减去1,因为个数前后计算两次,所以个数除以2才是对数。

代码:

#include<bits/stdc++.h>
#define endl '\n'
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef vector<int> vi;
#define check system("pause")
#define all(x) (x).begin(),(x).end()
#define de(a) cout<<#a<<" = "<<a<<endl
#define dd(a) cout<<#a<<" = "<<a<<" "
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define lowbit(a) ((a)&-(a))
#define INF 0x3f3f3f3f
const ll mod = 1e9+7;
const int N = 4e5+20;
#define dep(i,a,b) for(int i=(a);i>=(b);i--)
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define mes(p,b) memset(p,b,sizeof(p))
#define sz(x) int(x.size())
ll a[N],n,ans=0,b[N];
int main()
{
      ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    cin>>n;
    rep(i,1,n) cin>>a[i];
    rep(i,0,31){
        rep(j,1,n) b[j]=a[j]%(1<<(i+1));
        sort(b+1,b+1+n);
        int t=0;
        rep(j,1,n){
            t+=upper_bound(b+1,b+1+n,(1ll<<(i+1))-1-b[j])-lower_bound(b+1,b+1+n,(1ll<<i)-b[j]);
            t+=upper_bound(b+1,b+1+n,(1ll<<(i+2))-1-b[j])-lower_bound(b+1,b+1+n,(1ll<<i)+(1ll<<(i+1))-b[j]);
            //de(t);
            if((2*b[j])&(1<<i)) t--;
            
        }
        if((t/2)&1) ans+=(1<<i);
    }
    cout<<ans;
      return 0;
}

 

posted @ 2020-03-19 21:28  FZU_LH  阅读(162)  评论(0编辑  收藏  举报