判斷異或運算後二進位制下1個數為奇數的個數

2021-08-29 14:05:42 字數 3011 閱讀 2338

時限:1.5s

空間:64m

給你n ≤5

×107

n\leq5\times10^7

n≤5×10

7個數字,每個數字≤10

9\leq 10^9

≤109

,問你有多少對數字異或起來的值在二進位制下的1

11的個數為奇數個。

這個直接o(n

2)

o(n^2)

o(n2

)列舉計算就可以了,但是是肯定不行的,所以我們要考慮其他方法。

對於兩個數字,某一位異或為1

11的話那麼原來的兩個數字的那一位必須不一樣,如果異或為0

00的話,原來的兩個數字的兩位肯定一樣。

所以我們發現,它某一位從原來的1

11變成0

00的話,必須是同時都為1

11,那麼最後兩個數字的1

11減少的個數和肯定為偶數,所以我們只需要原來的1

11的個數和為奇數,那麼最後消除後剩下的1

11的個數肯定還是奇數,而只有兩個數的1

11的個數分別為一奇一偶,加起來才為奇數個。

110010xo

r010001

=100011

110010\ \mathbf\ 010001=100011

110010

xor0

1000

1=10

0011

原來有3+2

=5

3+2=5

3+2=5個1

11,而其中的順數第二位,兩個數字都為1

11,所以消去了,剩下3

33個1

11,那麼就為奇數。

11001xo

r00111

=11110

11001\ \mathbf\ 00111=11110

11001x

or00

111=

1111

0原來有3+3

=6

3+3=6

3+3=6個1

11,而順數最後一位都為1

11,消去,剩下4

44個1

11,所以不為奇數。

所以只有原來的1

11的個數為奇數的,最後才能成為答案。

所以最後統計一下奇數個1

11的個數,那麼答案就是奇數的和偶數的組合,令奇數個1

11的個數為t

tt個,那麼答案就為t×(

n−t)

t\times(n-t)

t×(n−t

)。如果直接統計的話,複雜度為o(n

logv

)o(nlogv)

o(nlog

v)的,而log

vlogv

logv

可以達到30

3030

,那麼複雜度最大為三億,顯然1.5

s1.5s

1.5s

是跑不過的,所以考慮優化:

我們按照位進行分治統計,複雜度降為o(n

logl

ogv)

o(nloglogv)

o(nlog

logv

).我們預處理15

1515

位的所有數的二進位制位的1

11的個數,那麼乙個數字可以看做兩個15

1515

位的數字拼接而成,所以拆開計算和即可,複雜度降為o(2

15+n)

o(2^+n)

o(215+

n)對於統計2

152^

215內的數的二進位制位的個數,我們不用15×2

1515\times 2^

15×215

列舉統計,我們可以用類似dp+

lowb

it

dp+lowbit

dp+low

bit的方式統計(low

bit(

i)=i

&(−i

)lowbit(i)=i\&(-i)

lowbit

(i)=

i&(−

i)為找到二進位制最低位的1

11),轉移如下:

b it

cnt[

i]=b

itcn

t[ix

orlo

wbit

(i)]

+1

bitcnt[i]=bitcnt[i\ \mathbf\ lowbit(i)]+1

bitcnt

[i]=

bitc

nt[i

xorl

owbi

t(i)

]+1我們發現它的實質是每次消除最低位的1

11,所以貢獻+1+1

+1即可。那麼複雜度即為o(2

15)

o(2^)

o(215)

。原題題目位址【in-luogu】

**如下:

#include

#include

#include

#define rg register

#define ll long long

#define lowbit(x) ((x)&(-x))

using

namespace std;

const

int s=

1<<15|

1,s=(1

<<15)

-1;ll n,a,b,c,d,x;

ll t1,bit[s]

;void

init()

}void

calc

(int a)

intmain()

printf

("%lld\n"

,1ll

*(n-t1)

*t1)

;return0;

}

二進位制位運算(與 或 異或 取反)

1.與運算 and 0 and 0 0 全1才1 1 and 0 0 0 and 1 0 1 and 1 1 用途 用來位置0,若想把ffh 11111111b,255d 第 三 五 從右往左 位置0,只需 and 11101011b 235d,e8h 2.或運算 or 0 or 0 0 全0才0 ...

二進位制 二進位制中1的個數

題目 請實現乙個函式,輸入乙個整數,輸出該數二進位制表示中 1 的個數。例如,把 9 表示成二進位制是 1001,有 2 位是 1。因此,如果輸入 9,則該函式輸出 2。示例 1 輸入 00000000000000000000000000001011 輸出 3 解釋 輸入的二進位制串 0000000...

判斷乙個整數二進位制下1的個數

1.最容易想到的就是 n 1 得到最後一位是不是 1 然後再將 n 1 這樣迴圈 int 32次就可以得到1的個數,但是這樣n為負數時會陷入死迴圈 2.不如換乙個思路設定乙個 i 每次讓i 1這樣就不會對n進行修改,避免了死迴圈 public static int getnum3 int n ret...