异或的性质及应用

本文探讨了异或运算的性质,包括交换律、结合律和自反性,并介绍了如何利用异或来交换两个数、进行异或前缀和计算以及在数组中寻找唯一或重复数字。通过分析Codeforces Round #717 (Div.2) B题,展示了在减少数组元素并保持所有元素相等的情况下,如何使用异或操作。提供了两种不同的解决方案,包括直接使用异或和通过前缀和判断。
摘要由CSDN通过智能技术生成

异或的性质及应用


前言

最近写了几道关于异或的题,在这里总结一下性质


一、性质

( 定义 : 0 ^ 0 = 0 , 1 ^ 1 = 0 , 1 ^ 0 = 1 , 0 ^ 1 = 1 )
(就像不进位的加法)

  1. 交换律

  2. 结合律

  3. 对任意数x,我们有:x ^ x=0 , x ^ 0=x

  4. 自反性:a ^ b ^ b = a ^ 0 = a
    故 a ^ b ^ c = d ^ e <=> d = a ^ b ^ c ^ e

  5. a ^ b = (!a) ^ (!b)

  6. !(a ^ b) = (!a) ^ b = a ^ (!b)

二、运用

  • 交换两个数
    好处是如交换 a 和 b可以节省一个中间变量的存储空间
    a = a ^ b
    b = b ^ a (b ^ a ^ b = a )
    a = a ^ b (a ^ b ^ a = b )

  • 异或前缀和,差分

  • 排除偶次重复
    例:在一个整数数组中,仅存在一个不重复的数字,其余数字均出现两次(或偶数次),找出不重复数字。
    解:将所有数字异或即可得到答案

  • 找数组中重复的数字
    例: 在一个整数数组中,只有一个数字重复出现了两次,其余的数字都只出现了一次,找出那个重复数字。
    解:先将数组所有成员全部异或得到结果a,再将每种数字全部异或得到结果b,a ^ b 即为重复数字。
    相比和式相减,能有效的防止溢出。


三、例题

Codeforces Round #717 (Div. 2)
B. AGAGA XOOORRR

Baby Ehab is known for his love for a certain operation. He has an array a of length n, and he decided to keep doing the following operation on it:

he picks 2 adjacent elements; he then removes them and places a single integer in their place: their bitwise XOR. Note that the length of the array decreases by one.
Now he asks you if he can make all elements of the array equal. Since babies like to make your life harder, he requires that you leave at least 2 elements remaining.

Input
The first line contains an integer t (1≤t≤15) — the number of test cases you need to solve.

The first line of each test case contains an integers n (2≤n≤2000) — the number of elements in the array a.

The second line contains n space-separated integers a1, a2, …, an (0≤ai<230) — the elements of the array a.

Output
If Baby Ehab can make all elements equal while leaving at least 2 elements standing, print “YES”. Otherwise, print “NO”.

Example
input
2
3
0 2 2
4
2 3 1 10

output
YES
NO

分析:
如果我们最后能得到所有元素都相同的一个数组,那么这个数组元素个数要么是奇数要么是偶数。
故直接上代码吧

法一:
#include<iostream>
#include<algorithm>
#include<cstdio>
#define N 2005
using namespace std;

int a[N];
inline int read()
{
   
    char ch=getchar();
    int flag=1,ans=0;
    while(ch<'0'
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值