ABC365:E - Xor Sigma Problem(位运算)

问题陈述

给你一个长度为 NN 的整数序列 A=(A1,…,AN)A=(A1​,…,AN​) 。求以下表达式的值:

∑i=1N−1∑j=i+1N(Ai⊕Ai+1⊕…⊕Aj)i=1∑N−1​j=i+1∑N​(Ai​⊕Ai+1​⊕…⊕Aj​) .

关于位向 XOR 的说明 非负整数 AA 和 BB 的位向 XOR 定义如下,表示为 A⊕BA⊕B :

  • 在 A⊕BA⊕B 的二进制表示中,当且仅当 AA 和 BB 的二进制表示中 2k2k 位上的数字中恰好有一位是 11 时, 2k2k ( k≥0k≥0 )位上的数字是 11 ;否则,它是 00 。

例如, 3⊕5=63⊕5=6 }(二进制: 011⊕101=110011⊕101=110 )。
一般来说, kk 个整数 p1,…,pkp1​,…,pk​ 的比特 XOR 定义为 (⋯((p1⊕p2)⊕p3)⊕⋯⊕pk)(⋯((p1​⊕p2​)⊕p3​)⊕⋯⊕pk​) 。可以证明这与 p1,…,pkp1​,…,pk​ 的阶数无关。

限制因素
  • 2≤N≤2×1052≤N≤2×105
  • 1≤Ai≤1081≤Ai​≤108
  • 所有输入值均为整数。
#include <bits/stdc++.h>
using namespace std;
int n;
long long a[200010];
long long sum;
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%lld",&a[i]);
        sum+=a[i];
    }
    
    long long ans=0;
    for(int i=0;i<=32;i++){
        
        //cnt0和cnt1分别是 第一个数到某个数的异或和为0的个数,异或和为1的个数(即左端点个数)。 
        //x是第1个数到当前的异或和 
        long long cnt0=0,cnt1=0,x=0;
        
        for(int j=0;j<=n;j++){//枚举右端点 
            
            //a[j]的第i位的二进制数 
            long long tmp=a[j]>>i&1;
            
            //第1个数到当前的异或和 
            x^=tmp;
            
            //cnt0个区间的异或和有2的i次方 
            if(x) ans+=(1<<i)*cnt0,cnt1++;
            
            //cnt1个区间的异或和有2的i次方 
            else ans+=(1<<i)*cnt1,cnt0++;
            
        }
        
    }
    
    cout<<ans-sum;//重复加了只含自己本身的区间 
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值