位运算 异或篇
位运算大法好…
基础篇:
异或,就是相同为0 ,相斥为1。
举个栗子:
10001
^
11001 =01000
大家一开始看到这东西的时候一定觉得so easy,觉得这个玩意没啥子用。(我一开始也是这样想的 )实际上,这是你没有了解异或的实际意义,下面来讲讲我对异或的理解:
首先,我要再次强调,计算机内的运算都是以二进制运算来进行的。
所以,大家看看这个式子:
1+2+3+4-1-2-3=4
如果把它化为二进制运算的话:
0001(1)
+0010(2)
+0011(3)
+0100(4)
_0001(1)
_0010(2)
_0011(3)
=0100(4)
大家通过这个式子看出来了什么吗?如果没有感觉,就把他再具体一点:
0001(1)
_0001(1)
+0010(2)
_0010(2)
+0011(3)
_0011(3)
+0100(4)
=0100(4)
你看:如果把上式转化为位运算的话,可以表示成这种东西:
0001(1)
^0001(1)
^0010(2)
^0010(2)
^0011(3)
^0011(3)
^0100(4)
=0100(4)
看到这里,其实异或的实际意义已经出来了
^的作用就是消消乐,如果一个式子中出现了两个同样的数就会消去,如果是一个数字就会保留,但当两个不同的数异或的时候,不能简单视为相加或相减,具体请看代码:
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
int n;
n = 3^ 2;
cout << n << endl;
n = n ^ 3;
cout << n << endl;
return 0;
}
第一个n执行的相当于3-2(不可以简单理解成加减)。之后的n^3就和上文所说,消消乐。所以结果输出为2。
看完这些,你可以去做一做洛谷P1469 这是一道很经典的关于异或的题。
AC代码如下:
#include<iostream>
#include<cstdio>
using namespace std;
#define ll long long
int main()
{
int n;
cin >> n;
ll t;
ll sum = 0;
for (int i = 0; i < n; i++)
{
scanf("%lld",&t);
sum = sum ^ t;
}
cout << sum << endl;
return 0;
}