ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

子数组异或和

2022-08-14 00:05:05  阅读:125  来源: 互联网

标签:前缀 int LL 偶数 异或 数组 include


子数组异或和

题目链接: https://www.acwing.com/problem/content/4510/

其他相关题解点这里

思路

异或俗称“不进位加法”.

如果x = y则有x ^ y = 0

这个题根据这个性质来写

首先预处理前缀异或和数组s[]

然后找哪个一段区间异或和为0,并且数量为偶数个

即区间(i,j]([i+1,j]),s[i] ^ s[j] = 0i - j为偶数

等价于在[0,i-1]中找一个s[j],它和s[i]的值相等,并且使得i - j为偶数.

image

查找一个值出现的次数,可以用哈希表来存(出现的次数),这样可以使得查找时间复杂度为O(1),要求i-j为偶数,可以将前缀异或和分奇数偶数下标来存到哈希表中,这样查找的时候只需判断i为奇数还是偶数即可.

代码

#include<iostream>
#include<algorithm>
#include<unordered_map>

using namespace std;

typedef long long LL;
const int N = 3e5 + 10;

LL a[N];

int main()
{
    int n;
    scanf("%d",&n);
    
    for(int i = 1; i <= n; i ++) scanf("%lld",&a[i]);
    
    unordered_map<int,int> h[2]; // 要开两个哈希表,一个存奇数,一个存偶数
    LL res = 0;
    LL sum = 0; // 前缀异或和
    h[0][sum] ++; // 将偶数前缀和s[0]存入
    
    for(int i = 1; i <= n; i ++)
    {
        sum = sum ^ a[i];
        res += h[i % 2][sum]; // i为偶数 前缀和存到h[0]中,奇数存到h[1]中
        h[i % 2][sum] ++;
    }
    
    printf("%lld",res);
    
    return 0;
}

标签:前缀,int,LL,偶数,异或,数组,include
来源: https://www.cnblogs.com/rdisheng/p/16584587.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有