Xor Sum 2二分/尺取 区间异或和等于区间和的方案数

简介: 对于一个左端点l和右端点r,如果说l->r之间满足区间异或和等于区间和,那么说从l -> r-1也是满足的,所以说此时对答案的贡献便是区间的长度r - l + 1,我们只需要找满足情况的最右端的端点就好,然后统计对答案的贡献区间的个数会爆掉int,记得开long long二分的时候直接将l or r 当成区间的端点可能不太准确,需要将每次的mid用一个变量记录下来二分代码:

题目描述


There is an integer sequence A of length N.

Find the number of the pairs of integers l and r (1≤l≤r≤N) that satisfy the following condition:

Al xor Al+1 xor … xor Ar=Al + Al+1 + … + Ar

Here, xor denotes the bitwise exclusive OR.


Definition of XOR

Constraints

1≤N≤2×105

0≤Ai<220

All values in input are integers.


输入


Input is given from Standard Input in the following format:

N

A1 A2 … AN


输出


Print the number of the pairs of integers l and r (1≤l≤r≤N) that satisfy the condition.


样例输入 Copy

4

2 5 4 6


样例输出 Copy

5


提示


(l,r)=(1,1),(2,2),(3,3),(4,4) clearly satisfy the condition. (l,r)=(1,2) also satisfies the condition, since A1 xor A2=A1 + A2=7. There are no other pairs that satisfy the condition, so the answer is 5.


求出有多少个区间(l,r) 满足区间的异或和等于区间和


区间异或和 与 区间和 在处理完前缀之后,会满足:

a[l] + a[l+1] + .... == sum[r] - sum[l-1]
a[l] ^ a[l+1] ^ ... == xorSum[r] ^ xorSum[l-1]


对于一个左端点l和右端点r,如果说l->r之间满足区间异或和等于区间和,那么说从l -> r-1也是满足的,所以说此时对答案的贡献便是区间的长度r - l + 1,我们只需要找满足情况的最右端的端点就好,然后统计对答案的贡献


区间的个数会爆掉int,记得开long long

二分的时候直接将l or r 当成区间的端点可能不太准确,需要将每次的mid用一个变量记录下来


二分代码:


typedef int itn;
int n,k;
ll a[maxn];
ll s[maxn];
ll sxor[maxn];
int main()
{
  n = read;
  for(int i=1;i<=n;i++) a[i] = read;
  for(int i=1;i<=n;i++){
    s[i] = s[i-1] + a[i];
    sxor[i] = sxor[i-1] ^ a[i];
  }
  ll ans = 0;
  for(int i=1;i<=n;i++){
    int l = i,r = n;
    int t = 0;
    while(l <= r){
      int md = (r + l) >> 1;
      if(s[md] - s[i-1] == (sxor[md] ^ sxor[i-1])){
        l = md + 1;
        t = md;
      }
      else r = md - 1;
    }
    ans += t - i + 1;
  }
  cout << ans << endl;
    return 0;
}


尺取代码:


typedef int itn;
int n,k;
ll a[maxn];
ll s[maxn];
ll sxor[maxn];
int main()
{
    n = read;
    for(int i=1;i<=n;i++) a[i] = read;
    ll ans = 0;
    for(int i=1;i<=n;i++) s[i]=s[i-1]+a[i],sxor[i] = sxor[i-1] ^ a[i];
    ll sum = 0;
    int l = 1;
    for(int i=1;i<=n;i++){
        while((sum^a[i]) != sum + a[i]){
            sum ^= a[l];
            l ++;
        }
        sum ^= a[i];
        ans += i - l + 1;
    }
    cout << ans <<endl;
    return 0;
}
/**************************************************************
    Problem: 7731
    Language: C++
    Result: 正确
    Time:28 ms
    Memory:25468 kb
****************************************************************/




目录
相关文章
|
9月前
|
机器学习/深度学习 算法 测试技术
【排序 贪心】3107. 使数组中位数等于 K 的最少操作数
【排序 贪心】3107. 使数组中位数等于 K 的最少操作数
【排序 贪心】3107. 使数组中位数等于 K 的最少操作数
|
9月前
|
算法 测试技术 C#
【最大公约数 调和级数】2183.统计可以被 K 整除的下标对数目
【最大公约数 调和级数】2183.统计可以被 K 整除的下标对数目
|
9月前
|
算法 测试技术 C#
【最大公约数 排序】2344. 使数组可以被整除的最少删除次数
【最大公约数 排序】2344. 使数组可以被整除的最少删除次数
|
9月前
|
算法 前端开发
二的幂数组中查询范围内的乘积
二的幂数组中查询范围内的乘积
45 0
|
算法 测试技术 C#
C++二分算法的应用:乘法表中第k小的数
C++二分算法的应用:乘法表中第k小的数
小于等于K的最大子数组累加和
小于等于K的最大子数组累加和
判断10-105之间有多少个素数,并输出所有素数。【素数又称为质数,定义为在大于1的 自然数中,除了1和它本身以外不再有其他因数的数
判断10-105之间有多少个素数,并输出所有素数。【素数又称为质数,定义为在大于1的 自然数中,除了1和它本身以外不再有其他因数的数
122 0
计算 100 以内的偶数累加和
计算 100 以内的偶数累加和
61 0
|
自然语言处理 算法 Python
利用函数求出一个数组最大三个数的乘积
利用函数求出一个数组最大三个数的乘积
148 0
|
算法 C++ Python
每日算法系列【LeetCode 829】连续整数求和
每日算法系列【LeetCode 829】连续整数求和
133 0

热门文章

最新文章