01/10/2018, 11:12
Tính tổng a[i] XOR a[j]
Mình đã đọc đi đọc lại code nhưng vẫn không hiểu, mong mọi người có thể giải thích giúp mình. Cảm ơn nhiều.
![](/pictures/picfullsizes/2018/10/03/zkp1538562566.jpg)
#include <bits/stdc++.h>
using namespace std;
long n, a[1000005], b[1000005];
long long s = 0;
int main()
{
cin >> n;
for (long i = 1; i <= n; i++)
cin >> a[i];
for (int i = 20; i >= 0; i--){
for (long u = 1; u <= n; u++)
if ( (a[u] >> i) % 2 == 0)
b[i]++; // dem so bit 0
}
for (long i = 0; i <= n; i++)
s += b[i] * (n - b[i]) * (1ll << i);
cout << s;
}
Bài liên quan
Format lại code bằng cách thêm 3 dấu ` vào đầu và cuối code, như thế này:
// code của bạn
Bạn format code xong thì mình mới đọc được code của bạn.
OK bạn, mình đã edit rồi đó.
Code khá tường minh đó. Khổ nỗi bị sai .
Bạn để ý rằng, trong 1 dãy xor, cứ có chẵn bit 1 thì kết quả của dãy bằng 0, nếu không thì bằng 1.
Cái gì xor 0 cũng bằng chính nó.
Ta sẽ sử dụng 2 tính chất trên vào bài này.
Lưu ý thêm,
a[i] ^ ... ^ a[j] = 1 số ghép bởi các bit, với mỗi bit k là kết quả của phép xor bit thứ k của các số a[i],... a[j]
, hayDòng trên không đúng về mặt lập trình, tuy nhiên mình sử dụng để bạn có thể mường tượng dễ hơn.
Limit bài này là 10^6 nên ta xét 20 bit. Với 20 bit, ta kiểm tra với mỗi bit i có bao nhiêu số a[u] có giá trị của bit i bằng 1. Các bit được đánh số từ phải sang trái. Bit 0 là bit tận cùng bên phải. Ví dụ:
Ta định nghĩa
Cách kiểm tra xem số a[u] có bit i bằng 1 hay không:
1 << i
làpow(2, i)
, nó biểu diễn dưới dạng nhị phân là100..00
(i chữ số 0). Xem ví dụ để hiểu dòng code trên hơn:Ta đã xong mảng b. Trích xuất kết quả:
Bạn nên đọc 1 tài liệu về bitwise để hiểu thêm.
Cảm ơn bạn vì sự chi tiết :D.
Cám ơn anh vì sự nhiệt tình :D.
Do xor tính trên từng bit nên ta xét bit thứ k của cả N số. Ta quan tâm đến số các bit 0 và số các bit 1 để tính số các bit 1 còn lại. Mà 1 xor 0 = 0 xor 1 = 1 nên kết quả tính là số bit 1 * số bit 0.
Vậy bài này quay trong O(N).
N <= 10^6, xấu nhất là có N / 2 bit 1 và N / 2 bit 0, có sợ nhân vào sẽ bị to quá không ạ?
Mình cũng tự hỏi là số 12 đó thớt tính ntn chứ sum này phải có int64, tối đa khoảng 10^12.