โจทย์ปัญหา
ได้รับจำนวนเต็มสองจำนวน x และ y และช่วงบิต [l, r] (1-indexed) ให้ คัดลอกบิตที่เป็น 1 จาก y ไป x เฉพาะในช่วงที่กำหนด คืนค่า x ที่แก้ไขแล้ว
ตัวอย่าง
Input: x = 10 (1010), y = 13 (1101), l = 2, r = 3
Binary:
x = 1010 y = 1101 Range [2,3]: bits 2-3 of y = 10 (binary) Copy to x: 1010 | 0100 = 1110 (14)
Output: 14
แนวคิดการแก้ปัญหา
- วนลูปบิต
iจากlถึงr - สร้าง Mask:
mask = 1 << (i-1)(1-indexed → 0-indexed) - ถ้า
y & maskเป็น 1 → Set bit ใน x:x |= mask
โค้ดตัวอย่าง (C++)
#include <bits/stdc++.h>
using namespace std;
void copySetBits(unsigned& x, unsigned y, unsigned l, unsigned r) {
// Validate range (1-32 for 32-bit unsigned)
if (l < 1 || r > 32) return;
for (int i = l; i <= r; i++) {
unsigned mask = 1u << (i - 1); // 1-indexed to 0-indexed
if (y & mask) {
x |= mask; // Set bit in x
}
}
}
int main() {
unsigned x = 10, y = 13, l = 2, r = 3;
copySetBits(x, y, l, r);
cout << "Modified x: " << x << endl; // 14
return 0;
}
ผลลัพธ์
Modified x: 14
Optimized Version (O(1) - No Loop)
void copySetBitsFast(unsigned& x, unsigned y, unsigned l, unsigned r) {
if (l < 1 || r > 32) return;
// Create mask for range [l, r]
unsigned mask = ((1u << (r - l + 1)) - 1) << (l - 1);
// Extract bits from y in range, apply to x
x |= (y & mask);
}
คำอธิบาย Optimized Version
(1u << (r - l + 1)) - 1→ สร้างบิต 1 ติดกัน (r-l+1) ตัว: เช่น r=3,l=2 → 3 bits → 111<< (l-1)→ เลื่อนไปตำแหน่งที่ถูกต้อง: 111 << 1 = 1110 (bits 2,3,4)y & mask→ ดึงเฉพาะบิตในช่วงจาก yx |= ...→ Set บิตเหล่านั้นใน x
Complexity Analysis
| Version | Time | Space |
|---|---|---|
| Loop | O(r-l+1) ≤ O(32) | O(1) |
| Optimized (Bitmask) | O(1) | O(1) |