异或


在无序数组中寻找两个出现奇数次的数

杀马特。学长 韩版系。学妹 提交于 2019-12-23 19:00:04
/** * 一个无序数组里有若干个整数,只有2个整数出现了奇数次,如何找到这2个出现奇数次的整数 * 解法:把2个出现奇数次的数命名为A和B,那么遍历整个数字进行异或,那么最终的异或 * 结果就是A和B的异或结果。在这个结果中,至少有一位会是1(如果都是0,则说明A和B相同 * ,则和题目不符)。 * 假设A和B中位为1的是第三位。则可以判断A和B中,有一个第三位为1,另一个第三位为0 * 然后以一个数二进制第三位是不是1来将整个数组分为2类,则A和B肯定在不同的类中 * 再对两个数组进行异或操作,分别得到两个出现奇数次的A和B。 */ public class FindLostNum { public static int [ ] findLostNum ( int [ ] array ) { int length = array . length ; int xorNum = 0 ; for ( int i = 0 ; i < length ; i ++ ) { xorNum = xorNum ^ array [ i ] ; } if ( xorNum == 0 ) return null ; int oneflag = 1 ; while ( ( xorNum & oneflag ) == 0 ) { oneflag = oneflag << 1 ; } int [ ]

位运算的基本操作【转载】

泄露秘密 提交于 2019-12-23 06:00:02
https://blog.csdn.net/mengzhengjie/article/details/80611422 leetcode 总结 位运算小结(按位与、按位或、按位异或、取反、左移、右移) 位运算不管是在 Java 语言,还是在C语言中,或者其他语言,都是经常会用到的,所以本文也就不固定以某种语言来举例子了,原始点就从0、1开始。位运算主要包括按位与(&)、按位或(|)、按位异或(^)、取反(~)、左移(<<)、右移(>>)这几种,其中除了取反(~)以外,其他的都是二目运算符,即要求运算符左右两侧均有一个运算量。 1、补码 在总结按位运算前,有必要先介绍下补码的知识,我们知道当将一个十进制正整数转换为二进制数的时候,只需要通过除2取余的方法即可,但是怎么将一个十进制的负整数转换为二进制数呢?其实,负数是以补码的形式表示,其转换方式,简单的一句话就是:先按正数转换,然后取反加1。 1 2 3 4 5 6 7 要将十进制的-10用二进制表示,先将10用二进制表示: 0000 0000 0000 1010 取反: 1111 1111 1111 0101 加1: 1111 1111 1111 0110 所以,-10的二进制表示就是:1111 1111 1111 0110 2、按位与(&) 参加运算的两个数,换算为二进制(0、1)后,进行与运算。只有当相应位上的数都是1时

按位与、或、异或等运算方法

╄→гoц情女王★ 提交于 2019-12-23 05:59:31
按位与运算符(&) 参加运算的两个数据,按二进制位进行“与”运算。 运算规则:0&0=0; 0&1=0; 1&0=0; 1&1=1; 即:两位同时为“1”,结果才为“1”,否则为0 例如:3&5 即 0000 0011 & 0000 0101 = 0000 0001 因此,3&5的值得1。 另,负数按补码形式参加按位与运算。 “与运算”的特殊用途: (1)清零。如果想将一个单元清零,即使其全部二进制位为0,只要与一个各位都为零的数值相与,结果为零。 (2)取一个数中指定位 方法:找一个数,对应X要取的位,该数的对应位为1,其余位为零,此数与X进行“与运算”可以得到X中的指定位。 例:设X=10101110, 取X的低4位,用 X & 0000 1111 = 0000 1110 即可得到; 还可用来 取X的2、4、6位。 按位或运算符(|) 参加运算的两个对象,按二进制位进行“或”运算。 运算规则:0|0=0; 0|1=1; 1|0=1; 1|1=1; 即 :参加运算的两个对象只要有一个为1,其值为1。 例如:3|5 即 0000 0011 | 0000 0101 = 0000 0111 因此,3|5的值得7。  另,负数按补码形式参加按位或运算。 “或运算”特殊作用: (1)常用来对一个数据的某些位置1。 方法:找到一个数,对应X要置1的位,该数的对应位为1,其余位为零

Bzoj3261 最大异或和

女生的网名这么多〃 提交于 2019-12-23 05:34:03
Time Limit: 10 Sec Memory Limit: 512 MB Submit: 1769 Solved: 747 Description 给定一个非负整数序列 {a},初始长度为 N。 有 M个操作,有以下两种操作类型: 1 、A x:添加操作,表示在序列末尾添加一个数 x,序列的长度 N+1。 2 、Q l r x:询问操作,你需要找到一个位置 p,满足 l<=p<=r,使得: a[p] xor a[p+1] xor ... xor a[N] xor x 最大,输出最大是多少。 Input 第一行包含两个整数 N ,M,含义如问题描述所示。 第二行包含 N个非负整数,表示初始的序列 A 。 接下来 M行,每行描述一个操作,格式如题面所述。 Output 假设询问操作有 T个,则输出应该有 T行,每行一个整数表示询问的答案。 Sample Input 5 5 2 6 4 3 6 A 1 Q 3 5 4 A 4 Q 5 7 0 Q 3 6 6 对于测试点 1-2,N,M<=5 。 对于测试点 3-7,N,M<=80000 。 对于测试点 8-10,N,M<=300000 。 其中测试点 1, 3, 5, 7, 9保证没有修改操作。 对于 100% 的数据, 0<=a[i]<=10^7。 Sample Output 4 5 6 HINT 对于 100% 的数据, 0<

按位与、或、异或等运算方法

扶醉桌前 提交于 2019-12-23 00:20:06
按位与运算符(&) 参加运算的两个数据,按二进制位进行“与”运算。 运算规则:0&0=0; 0&1=0; 1&0=0; 1&1=1; 即:两位同时为“1”,结果才为“1”,否则为0 例如:3&5 即 0000 0011 & 0000 0101 = 0000 0001 因此,3&5的值得1。 另,负数按补码形式参加按位与运算。 “与运算”的特殊用途: (1)清零。如果想将一个单元清零,即使其全部二进制位为0,只要与一个各位都为零的数值相与,结果为零。 (2)取一个数中指定位 方法:找一个数,对应X要取的位,该数的对应位为1,其余位为零,此数与X进行“与运算”可以得到X中的指定位。 例:设X=10101110, 取X的低4位,用 X & 0000 1111 = 0000 1110 即可得到; 还可用来取X的2、4、6位。 按位或运算符(|) 参加运算的两个对象,按二进制位进行“或”运算。 运算规则:0|0=0; 0|1=1; 1|0=1; 1|1=1; 即 :参加运算的两个对象只要有一个为1,其值为1。 例如:3|5 即 0000 0011 | 0000 0101 = 0000 0111 因此,3|5的值得7。  另,负数按补码形式参加按位或运算。 “或运算”特殊作用: (1)常用来对一个数据的某些位置1。 方法:找到一个数,对应X要置1的位,该数的对应位为1,其余位为零

海明码,码距,海明校验码

依然范特西╮ 提交于 2019-12-20 07:02:50
海明校验码是由RichardHamming于1950年提出、目前还被广泛采用的一种很有效的校验方法。它的实现原理,是在k个数据位之外加上r个校验位,从而形成一个k+r位的新的码字,使新的码字的码距比较均匀地拉大。 这种海明校验的方法只能检测和纠正一位出错的情况。所以如果有多个错误,就不能查出了。 什么是码距? 两个码组对应位上数字的不同位的个数称为码组的距离,简称码距,又称海明(Hamming)距离。 计算码距的一种方法,就是对两个位串进行异或(xor)运算,并计算出异或运算结果中1的个数。 例如110和011这两个位串,对它们进行异或运算,其结果是: 110⊕011=101; 异或结果中含有两个1,因此110和011之间的码距就等于2。 简单来说,就是,两对应相同位数的不同即码距+1,从首位开始对应; 例如00110和00100码距为1,12345和13344码距为2,Caus和Daun码距为2, 1011001和10110110码距d=2 校验码 海明校验码公式(假设为 k个数据位 设置 r个校验位 ) 2^r-1>=k+r(能得知r和k的关系) 码:101 即 k=3 2^r-r>=k+1=4 易错点:2^r=r个2相乘,不是2乘r 选最小的码距 最小r为3 海明码长度:r+k=3+3=6 注意:海明校验码是放在2的幂次位上的,即“1,2,4,8,16,32······ ”

线性基总结

半腔热情 提交于 2019-12-20 02:32:05
线性基    线性基是向量空间的一组基,通常可以解决有关异或的一些题目。通俗一点的讲法就是由一个集合构造出来的另一个集合,它有以下几个性质: 线性基的元素能相互异或得到原集合的元素的所有相互异或得到的值。 线性基是满足性质 1 的最小的集合。 线性基没有异或和为 0 的子集。 线性基中每个元素的异或方案唯一,也就是说,线性基中不同的异或组合异或出的数都是不一样的。 线性基中每个元素的二进制最高位互不相同。 线性基中每个元素的二进制最高位互不相同。    构造线性基的方法如下   对原集合的每个数 \(x\) 转为二进制,从高位向低位扫,对于第 \(i\) 位是 \(1\) 的,如果 \(p_i\) 不存在,那么令 \(p_i = x\) 并结束扫描,如果存在,令 \(x = x\) \(\oplus\) \(p_i\) 。 inline void insert(long long x) { for (int i = 55; i + 1; i--) { if (!(x >> i)) // x的第i位是0 continue; if (!p[i]) { p[i] = x; break; } x ^= p[i]; } } 查询原集合内任意几个元素 \(xor\) 的最大值,就可以用线性基解决。 将线性基从高位向低位扫,若 $xor \(上当前扫到的\) a_x$答案变大,就把答案异或上

Java中的位运算

烂漫一生 提交于 2019-12-20 00:29:42
  最近饶有兴致,看了一些java源代码,发现源码里面一些精巧的实现是通过位运算实现的,比如十进制整数转成十六进制形式字符串输出: 1 public static String toHexString(int i) 2 { 3 return toUnsignedString(i, 4); 4 } 5 6 private static String toUnsignedString(int i, int shift) { 7 char[] buf = new char[32]; 8 int charPos = 32; 9 int radix = 1 << shift; 10 int mask = radix - 1; 11 do { 12 buf[--charPos] = digits[i & mask]; 13 i >>>= shift; 14 } while (i != 0); 15 16 return new String(buf, charPos, (32 - charPos)); 17 } 18 19 final static char[] digits = { 20 '0' , '1' , '2' , '3' , '4' , '5' , 21 '6' , '7' , '8' , '9' , 'a' , 'b' , 22 'c' , 'd' , 'e' , 'f' , 'g

P4551 最长异或路径 题解

点点圈 提交于 2019-12-18 14:50:19
P4551 最长异或路径 Trie-字典树-图论 给出一个无根树,每条边有边权,求一条路径,使得这条路径上的边权异或和最大 下面一些关于异或最短路和证明: 与普通最短路不一样的是,这里最短路的距离求的是异或和,而这里的关键就是异或的重要性质:逆反性 首先,随便选一个点 s s s 当起点,跑一边最短路,求出dis数组, d i s [ x ] dis[x] d i s [ x ] 表示点 x x x 到起点的最短路长度。 当询问点 x x x 到点 y y y 的最短路时,分两种情况: 点 x x x 到点 y y y 的最短路径经过点 s s s ,那 x x x 到 y y y 的最短路就是 dis[x]^dis[y] 点 x x x 到点 y y y 的最短路径不经过点 s s s ,如下图: x x x 到 y y y 的最短路为 c c c , d i s [ x ] = a dis[x]=a d i s [ x ] = a 的话,可证明出 dis[y]=a ^ c ,而这样的话 dis[x] ^ dis[y] = a ^ c ^ a = c 所以,点 x x x 到点 y y y 的最短路还是 dis[x]^dis[y] 上面证明我的博客 题解 P5651 【基础最短路练习题】 ,那题也是求异或和最短路 找出异或的性质后,第一个想到的肯定是 O ( n 2 ) O(n

leetcode -- Single Number

我怕爱的太早我们不能终老 提交于 2019-12-18 13:37:03
Given an array of integers, every element appears twice except for one. Find that single one. Could you implement it without using extra memory? [解题思路] 以前看书时遇到过,一个数组中有一个元素出现一次,其他每个元素都出现两次 要求空间复杂度为O(1) 由于两个相同的元素异或的结果为0,而0^a==a,将数组中所有元素都进行异或,得到结果就是只出现一次的元素 1 public class Solution { 2 public int singleNumber(int[] A) { 3 // Note: The Solution object is instantiated only once and is reused by each test case. 4 if(A == null || A.length == 0){ 5 return 0; 6 } 7 int result = A[0]; 8 9 for(int i = 1; i < A.length; i++){ 10 result = result ^ A[i]; 11 } 12 return result; 13 } 14 } 本题扩展 1.一个数组中有两个元素只出现一次

工具导航Map