背景1:最多有1e6+1個數,其中只有乙個數出現了奇數次,請找出這個數(資料大小為 int 範圍)
利用原理:兩個相同的數異或值為0
解決方案:將所有數異或一次,最後得到的值就是出現奇數次的那個數
複雜度o(n)
背景2:最多有1e6個數,其中有兩個數出現了奇數次,請找出這兩個數(資料大小為 int 範圍)
利用原理仍然是兩個相同的數異或值為0,不過還需要我們考慮到的是,首先這兩個數肯定不同,
否則相同的兩個數分別出現奇數次,最後就是這個數出現了偶數次(與題意矛盾)
所以我們可以得到的是將所有數異或一遍以後會得到乙個非零數,而這個非零數有重要的性質
如果我們把這個數轉化為二進位制數,例如下面這個數
0 0 1 0 1 1 0
我們觀察為1的那三位,選出其中一位來,比如可以選倒數第2位,那麼要使這一位最後異或結果為1
那麼我們需要奇數個倒數第2位為1的數(二進位制)相異或才能使最後的結果為1,說明出現奇數次的兩個
數中,其中必定有乙個數的二進位制倒數第2位為1,另乙個數二進位制倒數第2位為0。
反證一下,如果兩個數二進位制倒數第2位都為1或都為0,那麼最後異或的次數為(奇+奇+其他出現偶數次的數==偶數次)
最後倒數第二位應該為0,相互矛盾,所以原命題正確。
有這個結論後,我們只需要再將所有二進位制倒數第2位為1的數異或起來,就得到了題目要求的其中乙個數,
將這個數與最開始所有數異或以來得到的值進行一下異或就得到了另乙個數
複雜度o(n)
1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #include 9 #include 10 #include11 #include 12 #include
13 #include 14 #include 15
#define lson root<<1,l,mid
16#define rson root<<1|1,mid+1,r
17#define fi first
18#define se second
19#define ping(x,y) ((x-y)*(x-y))
20#define mst(x,y) memset(x,y,sizeof(x))
21#define mcp(x,y) memcpy(x,y,sizeof(y))
22using
namespace
std;
23#define gamma 0.5772156649015328606065120
24#define mod 1000000007
25#define inf 0x3f3f3f3f
26#define n 500050
27#define maxn 100001
28 typedef pairpii;
2930
int n,a[1000005
];31
32int
main()
42if(n==2)47
int cnt=0;48
while(1)52
int ans1=0;53
int k=1
<54for(i=1;i<=n;++i)
58int ans2=temp^ans1;
59if(ans1>ans2)swap(ans1,ans2);
60 printf("
%d %d\n
",ans1,ans2);61}
62return0;
63 }
異或的運用
異或是一種基於二進位制的位運算,用符號xor或者 表示,其運算法則是對運算子兩側數的每乙個二進位制位,同值取0,異值取1。它與布林運算的區別在於,當運算子兩側均為1時,布林運算的結果為1,異或運算的結果為0。異或的性質 1 交換律 a b b a 2 結合律 a b c a b c 3 對於任意的a...
異或運算 有趣的異或運算
異或運算可以看做是沒有進製的加法,按位異或運算,相同為0,不同為1。0 0 0 0 1 1 1 0 1 1 1 0 觀察運算結果我們發現,當與0做異或運算時,另一元值不變 而與1做異或運算時,另一元值值取反。根據以上異或運算的特徵,可以有以下用途,除方便直觀外,運算效能也更加優異。1 變數重置0 假...
異或性質運用
異或 的乙個很重要的性質是 a a 0 a 0 a 下面總結幾道運用到其性質的題目。例1 有兩個整型亂序陣列,其中乙個陣列比另外乙個多乙個數字,其他數字都一樣,讓你求出這兩個陣列相差的那個數字。要求時間複雜度為o n 思路 先分別求兩個陣列的異或,然後再將兩個陣列的異或結果再進行異或,最終結果就是答...