Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C++

XOR ของผลรวมทุกคู่ที่เป็นไปได้ในอาร์เรย์ (C++)

โจทย์

ได้รับอาร์เรย์ขนาด n สร้าง sequence ขนาด n×n โดยแต่ละองค์ประกอบคือผลรวมของคู่ (pair) ของทุกองค์ประกอบในอาร์เรย์กับตัวเอง แล้วหา XOR ของ sequence นี้ทั้งหมด

ตัวอย่าง

Input: A = {1, 4, 5}
Output: 0

คำอธิบาย

B = {1+1, 1+4, 1+5, 4+1, 4+4, 4+5, 5+1, 5+4, 5+5}
B = {2, 5, 6, 5, 8, 9, 6, 9, 10}
XOR = 2 ^ 5 ^ 6 ^ 5 ^ 8 ^ 9 ^ 6 ^ 9 ^ 10 = 0

ข้อสังเกตสำคัญ (Key Insight)

ในอาร์เรย์ B ที่สร้างขึ้น:

  • คู่ a[i] + a[j] และ a[j] + a[i] มีค่าเท่ากัน (commutative)
  • คู่เหล่านี้จะปรากฏเป็นคู่ (2 ครั้ง) ยกเว้นเมื่อ i = j
  • XOR ของค่าเดียวกัน 2 ครั้ง = 0 (cancel out)
  • เหลือเฉพาะคู่ที่ i = j คือ 2 * a[i] (หรือ a[i] + a[i])

ดังนั้น ผลลัพธ์ = XOR ของ 2 * a[i] สำหรับทุก i
= 2 * (a[0] ^ a[1] ^ ... ^ a[n-1])

โค้ดตัวอย่าง

#include <iostream>
using namespace std;

int findSumXor(int arr[], int n) {
    int XOR = 0;
    for (int i = 0; i < n; i++) {
        XOR ^= arr[i];
    }
    return XOR * 2;
}

int main() {
    int arr[3] = {2, 4, 7};
    int n = sizeof(arr) / sizeof(arr[0]);
    cout << "The xor of the sum pair of elements of the array is: " << findSumXor(arr, n);
    return 0;
}

ผลลัพธ์

The xor of the sum pair of elements of the array is: 2

ตรวจสอบ: 2 ^ 4 ^ 7 = 1, 1 * 2 = 2 ✓

การพิสูจน์ทางคณิตศาสตร์

ให้ S = a[0] ^ a[1] ^ ... ^ a[n-1]

ผลรวมทั้งหมดใน B = Σi,j (a[i] + a[j])

แยกเป็น: Σi≠j (a[i] + a[j]) + Σi (2*a[i])

สำหรับ i≠j: (a[i]+a[j]) และ (a[j]+a[i]) เป็นคู่ที่เท่ากัน XOR กัน = 0

เหลือ: Σi (2*a[i]) = 2 * Σi a[i] (ในความหมายของ XOR)

แต่ XOR ไม่ distribute over addition แบบปกติ... อย่างไรก็ตาม 2*x = x << 1 (left shift 1 bit)

และ XOR กับ left shift: (a ^ b) << 1 = (a<<1) ^ (b<<1) เพราะ XOR เป็น bitwise operation

ดังนั้น 2 * (a[0] ^ a[1] ^ ...) = (2*a[0]) ^ (2*a[1]) ^ ... ✓

Complexity

  • Time: O(N) - วนลูปเพียงครั้งเดียว
  • Space: O(1) - ใช้ตัวแปรคงที่

สรุป

โจทย์ที่ดูเหมือนต้องใช้ O(N2) สามารถลดเป็น O(N) ได้ด้วยการสังเกตคุณสมบัติของ XOR และคู่ที่ซ้ำกัน เป็นตัวอย่างคลาสสิกของการ "คิดก่อนเขียนโค้ด" ใน competitive programming