เพื่อแก้ปัญหาที่เราได้รับอาร์เรย์และแบบสอบถามบางอย่าง ตอนนี้ในแต่ละแบบสอบถาม เราได้รับช่วง ตอนนี้เราต้องหาตัวเลขที่ทำให้ผลรวมของ xor กับ x ขยายใหญ่สุด ตัวอย่างเช่น
Input : A = {20, 11, 18, 2, 13} Three queries as (L, R) pairs 1 3 3 5 2 4 Output : 2147483629 2147483645 2147483645
ในปัญหานี้ เราจะนับคำนำหน้าของ 1 ที่มีอยู่ในตัวเลขในแต่ละตำแหน่งในขณะนี้ เนื่องจากเราได้คำนวณจำนวนล่วงหน้าแล้ว ดังนั้น ในการหาจำนวนในช่วงที่กำหนดจาก L ถึง R เราจำเป็นต้อง ลบ สันนิษฐาน ถึง R โดย สันนิษฐาน ถึง L.
แนวทางในการหาแนวทางแก้ไข
ในแนวทางนี้ เนื่องจากเราต้องหาผลรวมสูงสุด เราจึงต้องทำให้บิตส่วนใหญ่ของ xor เท่ากับ 1 ดังนั้นเราจึงตรวจสอบว่าบิตใดมีค่ามากกว่า 0 หรือไม่ ดังนั้นเราจึงรีเซ็ตบิตของ x นั้น เนื่องจากตอนนี้ตัวเลขส่วนใหญ่มีบิตนั้นเท่ากับ 1 ดังนั้นเมื่อเราจับคู่ส่วนใหญ่ 1 กับ 0 ดังนั้นในที่สุดเราก็ได้เสียงส่วนใหญ่ บิตนั้นเท่ากับ 1 ดังนั้นเราจึงเพิ่มคำตอบให้สูงสุด
ตัวอย่าง
รหัส C++ สำหรับแนวทางข้างต้น
#include <bits/stdc++.h> using namespace std; #define MAX 2147483647 // 2^31 - 1 int prefix[100001][32]; // the prefix array void prefix_bit(int A[], int n){ // taking prefix count of 1's present for (int j = 0; j < 32; j++) // we keep 0th count as 0 and our prefix array starts with index 1 prefix[0][j] = 0; for (int i = 1; i <= n; i++){ // making our prefix array int a = A[i - 1]; // ith element for (int j = 0; j < 32; j++){ // as our number is less than 2^32 so we traverse for bit 0 to 31 int x = 1 << j; // traversing in bits if (a & x) // if this bit is one so we make the prefix count as prevcount + 1 prefix[i][j] = 1 + prefix[i - 1][j]; else prefix[i][j] = prefix[i - 1][j]; } } } int maximum_num(int l, int r){ int numberofbits = r - l + 1; // the number of elements in the range hence the number of bits int X = MAX; // we take the max value such that all of it's bits are one // Iterating over each bit for (int i = 0; i < 31; i++){ int x = prefix[r][i] - prefix[l - 1][i]; // calculating the number of set bits in the given range if (x >= numberofbits - x){ // is number of 1's is more than number of 0's int currentbit = 1 << i; // we set the current bit to prefix for toggling that bit in x X = X ^ currentbit; // we make toggle that bit from 1 to 0 } } return X; // answer } int main(){ int n = 5, q = 3; // number of element in our array and number of queries present int A[] = { 210, 11, 48, 22, 133 }; // elements in our array int L[] = { 1, 4, 2 }, R[] = { 3, 14, 4 }; // given queries prefix_bit(A, n); // creating prefix bit array for (int i = 0; i < q; i++) cout << maximum_num(L[i], R[i]) << "\n"; return 0; }
ผลลัพธ์
2147483629 2147483647 2147483629
คำอธิบายของโค้ดด้านบน
ในแนวทางนี้ ก่อนอื่นเราจะคำนวณจำนวนคำนำหน้าของ 1 ปัจจุบันสำหรับแต่ละบิต ตอนนี้เมื่อเราได้จำนวนนี้แล้ว เราก็ได้แก้ปัญหาที่ใหญ่ที่สุดของเราซึ่งก็คือการข้ามผ่านข้อความค้นหา ณ ตอนนี้ เราจะไม่ข้ามผ่านแต่ละช่วง ดังนั้นเราสามารถคำนวณมันผ่านอาร์เรย์คำนำหน้าของเราได้แล้ว ตรรกะหลักของเราคือ เราคำนวณจำนวนการรีเซ็ตและการตั้งค่าบิตในช่วงเมื่อเราพบตำแหน่งที่หมายเลขบิตที่ตั้งไว้มากกว่าจำนวนบิตรีเซ็ต ดังนั้นเราจึงรีเซ็ตบิตนั้นใน x ของเราทันทีเมื่อเราเริ่มต้น x ด้วย 2^31 - 1 ดังนั้นบิตทั้งหมดจะถูกตั้งค่า และเราพบคำตอบของเราโดยสลับบิตใน x
บทสรุป
ในบทช่วยสอนนี้ เราแก้ปัญหาเพื่อค้นหาจำนวนที่ผลรวมของ XOR กับช่วงอาร์เรย์ที่กำหนดเป็นค่าสูงสุด นอกจากนี้เรายังได้เรียนรู้โปรแกรม C++ สำหรับปัญหานี้และแนวทางที่สมบูรณ์ (ปกติ) ซึ่งเราแก้ไขปัญหานี้ เราสามารถเขียนโปรแกรมเดียวกันในภาษาอื่นๆ เช่น C, java, python และภาษาอื่นๆ เราหวังว่าคุณจะพบว่าบทช่วยสอนนี้มีประโยชน์