• 异或的性质与应用


    异或:

    任意一个数都可以表示成二进制的状态,那么两个数在二进制状态下,
    进行异或运算: 相同得 0 ,反之 得 1。
    a b ^
    1 1 1
    1 0 0
    0 1 0
    0 0 1
    

    性质:

    1、交换律: A ^ B = B ^ A
    2、结合律:(A ^ B) ^ C = A ^ (B ^ C)
    3、恒等律:X ^ 0 = X; 
    4、归零律:X ^ X = 0;
    5、自反:A ^ B ^ B = A ^ 0 = A;
    6、 对于任意的 X: X ^ (-1) = ~X;
    7、 如果 A ^ B = C 成立,那么 A ^ B = C,B ^ C = A;
    

    应用:

    1. 1-1000放在含有1001个元素的数组中,只有唯一的一个元素重复,找出这个重复的数字。要求不能使用辅助存储空间并且数组的每个元素只能访问一次。
    法一:
    将这1001个元素加起来的和减去1+2+……+1000,所得的值就是重复的数字(数据过大容易溢出)。
    法二:异或
    将1001个数全部异或得到的值再与1^2^……^1000的结果再次异或,这样就避免了数据过大溢出的情况。
    首先,异或运算满足交换律和结合律,即a^b = b^a,(a^b)^c = a^(b^c)。令重复的数字为n:
    所以1 ^ 2 ^ … ^ n ^ n ^ … ^ 1000 = 1 ^ 2 ^ … ^ 1000 ^ (n ^ n) = 1 ^ 2 ^ … ^ 1000 ^ 0 = 1 ^ 2 ^ … ^ 1000(即序列中除了重复数字 n 以外所有数的异或。
    如果令1 ^ 2 ^ … ^ 1000(序列中不包含n)的结果为T,那么1 ^ 2 ^ … ^ 1000(序列中包含n)的结果就是 T^n,T ^ (T ^ n) = n。
    法三: map
    用 map 判断某个元素是否已经出现过
    
    2. 变形:一个数组存放若干整数,一个数出现奇数次,其余数均出现偶数次,找出这个出现奇数次的数。
    奇数次 : A ^ A ^ A = A ^ 0 = A
    偶数次 :B ^ B = 0
    将所有值异或即可解决。
    
    3、给出n个数,会有q次询问,每次询问[L, R] 区间内所有出现次数为奇数的数的异或,如果这个区间内没有出现次数为奇数的数,那么输出0。
    与第二道应用类似,只是这里多了一个区间。
    其实与前缀和类似,我们可以求其前缀异或和 : sum[i] = sum[i - 1] ^ a[i]
    就可以得到某个区间的异或值 : sum[R] - sum[L - 1]
    为什么这个成立呢 ?
    假设 [1,L - 1] 的每个元素是 a1,a2,a3......a(L - 1)
         [L,R] 的每个元素是    a1,a2,a3.......a(L- 1).....a[R]
    将上下进行异或,最后就留下 L - R 这个区间的异或值.
    

    参考博客:https://blog.csdn.net/Jasmineaha/article/details/81412711

  • 相关阅读:
    python模块学习第 0000 题
    报错The VMware Authorization Service is not running
    图像指纹的重复识别
    CSS预编译器配置-------LESS Sass Stylus webstorm
    CSS布局中的水平垂直居中
    进度与日程
    HTML5 application cache
    进度
    CC2530芯片介绍
    Linux命令工具 top详解
  • 原文地址:https://www.cnblogs.com/prjruckyone/p/12302732.html
Copyright © 2020-2023  润新知