异或

在不占用额外空间的情况下,找出只出现一次的元素

╄→гoц情女王★ 提交于 2020-01-16 01:27:55
问题: 有一组数据,假设除了某一个元素出现了一次外,其余元素都出现了两次,怎么在 不占用额外空间 的情况下找出这个元素。 如: array[] = {2, 3, 2, 5, 1, 4, 6, 3, 1, 6, 4} 在这个数组中,怎么找出这个只出现了一次的5呢? 不限制空间的解答: 找出一组数据中只出现一次的数据 解法: 利用异或 异或是使用数据所对应的二进制值进行安慰异或,相同为0,不同为1。 因此当一组数据中所有的数据异或时,两两相同的数据会抵消,只剩下一个只出现一次的。 代码: # include <stdio.h> # include <string.h> int main ( int argc , char const * argv [ ] ) { int array [ ] = { 2 , 3 , 2 , 5 , 1 , 4 , 6 , 3 , 1 , 6 , 4 } ; int i = 0 ; int length = 0 ; length = sizeof ( array ) / sizeof ( array [ 0 ] ) ; for ( i = 1 ; i < length ; i ++ ) array [ 0 ] = array [ 0 ] ^ array [ i ] printf ( "%d\n" , array [ 0 ] ) return 0

【橘色小分队】snow的笔记@

风流意气都作罢 提交于 2020-01-16 01:24:08
Make Good 变棒棒 题意:有个序列,你可以添加最多三个数,使序列的 和 为 异或和 的两倍。 思路:先求出来异或和xor,和sum。然后添加的第一个数是xor,这样和变成了sum+xor,异或和变成了0;添加的第二个数是sum+xor,这样异或和变成了sum+xor,和变成了2*(sum+xor)。 Strange Device 奇怪的设备 题意:你有一个设备,它能告诉你你输入的下标对应的序列中第m大的是哪个、是几。你只能输入k个数。 思路:虽然有n个数,但其实k+1个就够了。大的数的出现次数就是m。 只有k+1个数,假设是按顺序排好的,不问前m(包括m)个的话,答案会是第m+1大的数,否则答案就是m。m+1大刚好出现m次,且一共只会有这两种答案。所以~嗯! Devide Points 分点点 题意:有许多点,把它们分成两堆。同一堆的点之间的距离不能等于不同堆之间的点的距离。 思路:把点按坐标奇偶分成 A偶偶、B奇偶or偶奇、C奇奇。 (以下的距离就认为是距离的平方吧~) 那么 AC和B是满足条件的 :因为AC内的点的距离一定是2的倍数,B内的距离也一定是2的倍数,AC和B之间的点的距离一定为奇数。 但是B有可能是空的,那么就 A和C :A内部一定为4的倍数,C内部一定为4的倍数,AC之间为2但不为4的倍数。 但C也有可能是空的,那么就把所有点的坐标除以2(所有点都在A中

2015年09月12日

☆樱花仙子☆ 提交于 2020-01-15 15:48:27
异或运算特性 a ^ b = c 则 c ^ b = a , c ^ a = b, 双向链表需要两个指针,一个指向前一个结点,一个指向后一个结点, 异或双向链表只用一个指针,该指针等于 前后两两个结点指针的异或的结果,这样节省了空间,但增加了计算。 一般的双向链表节点中包含两个指针,分别指向前驱和后继。异或指针双向链表的节点只有一个“指针”,这个指针是另外两个指针的“异或”值,并利用以下运算得到其前驱和后继的指针: a^(a^b)=b (a^b)^b=a 在C语言中,可以先把指针转换为无符号整型数然后进行异或,另外还应保存指向链表头尾节点的指针。 按照这种思路,节点中的这一个指针还可以是“加法”值,或者其他指针运算得到的值。如果是加法,可以利用以下运算得到其前驱和后继指针: (x+y)-x=y (x+y)-y=x 需要注意的是,这样的“加法”运算或“异或”运算都是针对指针的值本身的,即指针转换为无符号整型后的运算。不能跟指针运算(如两个指针相减)混淆。 异或指针双向链表的建立、遍历等参考如下实现。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51

leetcode 1310. 子数组异或查询(C++、python)

☆樱花仙子☆ 提交于 2020-01-14 18:10:27
有一个正整数数组 arr ,现给你一个对应的查询数组 queries ,其中 queries[i] = [Li, Ri] 。 对于每个查询 i ,请你计算从 Li 到 Ri 的 XOR 值(即 arr[Li] xor arr[Li+1] xor ... xor arr[Ri] )作为本次查询的结果。 并返回一个包含给定查询 queries 所有结果的数组。 示例 1: 输入:arr = [1,3,4,8], queries = [[0,1],[1,2],[0,3],[3,3]] 输出:[2,7,14,8] 解释: 数组中元素的二进制表示形式是: 1 = 0001 3 = 0011 4 = 0100 8 = 1000 查询的 XOR 值为: [0,1] = 1 xor 3 = 2 [1,2] = 3 xor 4 = 7 [0,3] = 1 xor 3 xor 4 xor 8 = 14 [3,3] = 8 示例 2: 输入:arr = [4,8,2,10], queries = [[2,3],[1,3],[0,0],[0,3]] 输出:[8,0,4,4] 提示: 1 <= arr.length <= 3 * 10^4 1 <= arr[i] <= 10^9 1 <= queries.length <= 3 * 10^4 queries[i].length == 2 0 <=

codeforces 242-E 区间异或

不羁岁月 提交于 2020-01-13 22:17:07
题目链接:https://codeforces.com/problemset/problem/242/E 题目大意: 给你n和a[i]…a[n]。 m个操作: 1 l r 查询a[L]+…+a[R] 2 l r x 思路:我们用多棵树维护每一位就可以了。 # include <bits/stdc++.h> # define LL long long using namespace std ; # define mid (l+r)/2 int a [ 100005 ] ; int sum [ 21 ] [ 400005 ] , add [ 21 ] [ 400005 ] ; void BT ( int rt , int l , int r , int x ) { if ( l == r ) { sum [ x ] [ rt ] = ( a [ l ] & ( 1 << x ) ) ? 1 : 0 ; return ; } BT ( rt << 1 , l , mid , x ) ; BT ( ( rt << 1 ) + 1 , mid + 1 , r , x ) ; sum [ x ] [ rt ] = sum [ x ] [ rt << 1 ] + sum [ x ] [ ( rt << 1 ) + 1 ] ; } void GXdown ( int rt , int x ,

143. 最大异或对

谁都会走 提交于 2020-01-13 01:59:02
在给定的N个整数A1,A2……AN中选出两个进行xor(异或)运算,得到的结果最大是多少? 输入格式 第一行输入一个整数N。 第二行输入N个整数A1~AN。 输出格式 输出一个整数表示答案。 数据范围 1≤N≤105, 0≤Ai<231 输入样例: 3 1 2 3 输出样例: 3 # include <bits/stdc++.h> using namespace std ; const int N = 100090 ; int pos = 1 , a [ N ] , T [ 3000010 ] [ 2 ] ; void Insert ( int x ) { int p = 0 ; for ( int j = 30 ; ~ j ; j -- ) { int n = x >> j & 1 ; if ( ! T [ p ] [ n ] ) T [ p ] [ n ] = pos ++ ; p = T [ p ] [ n ] ; } } int Find ( int x ) { int res = 0 , p = 0 ; for ( int j = 30 ; ~ j ; j -- ) { int n = x >> j & 1 ; if ( T [ p ] [ ! n ] ) { //¸ønÈ¡·´£¬ÕÒÕÒ¿´ÓÐûÓС°·´Â·¡± res + = 1 << j ; p = T [

线性基

a 夏天 提交于 2020-01-11 23:58:34
我们用高斯消元的方法来弄线性基。 首先,对于aiai,我们从高位到低位查看每一位,如果当前位数是1,那么就查看高斯消元矩阵的第jj行,假如jj行jj列是1,就将aiai每一位异或与第jj行每一位做异或,继续处理。否则将ai放置在第jj行,然后消元即可。 代码如下。 int n; scanf("%d",&n); ll x; for(int i=1;i<=n;i++) { scanf("%lld",&x); for(int j=60;j>=0;j--) { if(x>>j&1) { if(a[j])x^=a[j]; else { a[j]=x; break; /*或者 num++; a[j]=x; for(int k=j-1;k>=0;k--)if(a[k]&&(a[j]&bin[k]))a[j]^=a[k]; for(int k=j+1;k<=60;k++)if(a[k]&bin[j])a[k]^=a[j]; break; */ } } } } https://www.luogu.com.cn/problem/P3812 #include <stdio.h> #define ll long long ll a[55]; int main() { int n; scanf("%d",&n); ll x; for(int i=1;i<=n;i++) { scanf("%lld",&x);

Java面试题26——运算符优先级

故事扮演 提交于 2020-01-11 08:48:36
运算符优先级 1.Java中的运算符优先级: 口诀:单目乘除为关系,逻辑三目后赋值。(大佬总结的) 口诀解释: 单目:指的是例如正负(±)这些一次只作用于一个变量的运算符,又叫一元运算符。 乘除:乘、除、模 ,毫无疑问优先级比加减高一级 为:即谐音“位”,指的是位运算中用到的符号:~(按位取反)<<(左移) >>(右移),^(也可以位运算,二进制异或)。 关系:大于、大于等于、小于、小于等于 逻辑:指的是异或、与、或三个逻辑运算符 三目:即三目运算符:条件运算符A > B ? X : Y 赋值:赋值运算符 具体的运算符排序如下:可以看到与我们的口诀不同的是,位运算符(按位与、按位或、按位异或)优先级排在关系运算符的后面。但是>>,<<,>>>等位运算符在关系运算符前面。~(按位取反)优先级很高。 这里的结合性是指运算符结合的顺序,通常都是从左到右。从右向左的运算符最典型的就是负号,例如3±4,则意义为3加-4,符号首先和运算符右侧的内容结合。 来源: CSDN 作者: 子衿@ 链接: https://blog.csdn.net/huiyanfreeflying/article/details/103914219

位运算和二进制枚举2020.1.3

时光毁灭记忆、已成空白 提交于 2020-01-11 01:47:25
异或 A^B 两数不同才是1。 通常用于对二进制的特定一位进行取反,可以对两个数进行交换。 常用性质:A^B^B=A,即B^B=0,可以用作判断一个数出现的次数,0^A=A,并且可以用作字符串的比较。 异或也叫半加运算,其运算法则相当于 不带进位的二进制加法 一数异或同一个数两次,则结果还是原数,即 (a ^ b) ^ b = a 0异或任何数,结果都等于那个数,即 0 ^ a = a 与 A&B 同为1才是1。 通常用于二进制位操作,如一个数&1的结果就是取二进制的最末尾,可以用来判断整数奇偶。 左移 (<<) 乘2 右移(>>)除2 用1或0来判断取或者不取 Find different 题目翻译 Description 给出一个奇数n(1<=n<=10000001)。 给你一个含有n个数的数组:a[1],a[2],a[3] … a[n],他们都是正整数。 有n/2个数字出现两次,只有1个数字出现一次。 现在你需要指出只出现一次的那个数字。 Input 有多个测试用例,以EOF结束。 第一行是一个整数n。 第二行有n个整数a[1],a[2]…a[n]。 # include <bits/stdc++.h> using namespace std ; int n ; int main ( ) { while ( cin >> n ) { int x1 , xn ; cin >>

十六进制字符串异或实现

被刻印的时光 ゝ 提交于 2020-01-10 20:53:07
/// <summary> /// 十六进制字符串异或操作 /// </summary> /// <param name="hex"></param> /// <param name="xor"></param> /// <returns></returns> public static string ConvertHexToXor2(string hex,string xor) { string newstring = ""; for (int i = 0; i < hex.Length; i += 2) { string str = hex.Substring(i, 2); if (xor != "") { newstring += (Convert.ToInt64(xor, 16) ^ Convert.ToInt64(str, 16)).ToString("X2"); } else { xor = str; } } return newstring; } /*--> */ /*--> */ /*--> */ /*--> */ 来源: https://www.cnblogs.com/zhangwenbo0713/p/10956921.html