इस लेख में, हमने एक समस्या दी है जिसमें हमें पूर्णांकों की एक सरणी दी गई है, और हमें बिटवाइज़ और दी गई श्रेणियों को खोजने का काम सौंपा गया है, उदाहरण के लिए 7minus;
Input: arr[ ] = {1, 3, 1, 2, 32, 3, 3, 4, 4}, q[ ] = {{0, 1}, {3, 5}}
Output:
1
0 0
1 AND 31 = 1
23 AND 34 AND 4 = 00
Input: arr[ ] = {1, 2, 3, 4, 510, 10 , 12, 16, 8}, q[ ] = {{0, 42}, {1, 33, 4}}
Output:
0 8
0 हम पहले पाशविक बल दृष्टिकोण को लागू करने जा रहे हैं और इसकी समय जटिलता की जाँच करेंगे। यदि हमारी समय जटिलता पर्याप्त नहीं है, तो हम एक बेहतर दृष्टिकोण विकसित करने का प्रयास करेंगे।
क्रूर फ़ोर्स अप्रोच
दिए गए दृष्टिकोण में, हम दी गई सीमा को पार करेंगे और अपना उत्तर ढूंढेंगे और उसे प्रिंट करेंगे।
उदाहरण
#include <bits/stdc++.h>
using namespace std;
int main() {
int ARR[] = { 10, 10 , 12, 16, 8 };
int n = sizeof(ARR) / sizeof(int); // size of our array
int queries[][2] = { {0, 2}, {3, 4} }; // given queries
int q = sizeof(queries) / sizeof(queries[0]); // number of queries
for(int i = 0; i < q; i++) { // traversing through all the queries
long ans = 1LL << 32;
ans -= 1; // making all the bits of ans 1
for(int j = queries[i][0]; j <= queries[i][1]; j++) // traversing through the range
ans &= ARR[j]; // calculating the answer
cout << ans << "\n";
}
return 0;
} आउटपुट
8 0
इस दृष्टिकोण में, हम प्रत्येक क्वेरी की श्रेणियों के माध्यम से एक लूप चलाते हैं और उनके सामूहिक बिटवाइज़ प्रिंट करते हैं, और इसलिए हमारे कार्यक्रम की समग्र जटिलता O(N*Q) बन जाती है , जहां एन हमारे सरणी का आकार है और क्यू अब हमारे प्रश्नों की संख्या है क्योंकि आप देख सकते हैं कि यह जटिलता उच्च बाधाओं के लिए उपयुक्त नहीं है, इसलिए हम इस समस्या के लिए एक तेज़ दृष्टिकोण के साथ आएंगे।
कुशल दृष्टिकोण
इस समस्या में, हम दिए गए रेंज में सेट बिट्स के योगदान की जाँच करके बिटवाइज़ और दी गई रेंज की गणना करने के लिए एरे के प्रीफ़िक्स बिट काउंट का पूर्व-गणना करते हैं।
उदाहरण
#include <bits/stdc++.h>
using namespace std;
#define bitt 32
#define MAX (int)10e5
int prefixbits[bitt][MAX];
void bitcount(int *ARR, int n) { // making prefix counts
for (int j = 31; j >= 0; j--) {
prefixbits[j][0] = ((ARR[0] >> j) & 1);
for (int i = 1; i < n; i++) {
prefixbits[j][i] = ARR[i] & (1LL << j);
prefixbits[j][i] += prefixbits[j][i - 1];
}
}
return;
}
int check(int l, int r) { // calculating the answer
long ans = 0; // to avoid overflow we are taking ans as long
for (int i = 0; i < 32; i++){
int x;
if (l == 0)
x = prefixbits[i][r];
else
x = prefixbits[i][r] - prefixbits[i][l - 1];
if (x == r - l + 1)
ans = ans | 1LL << i;
}
return ans;
}
int main() {
int ARR[] = { 10, 10 , 12, 16, 8 };
int n = sizeof(ARR) / sizeof(int); // size of our array
memset(prefixbits, 0, sizeof(prefixbits)); // initializing all the elements with 0
bitcount(ARR, n);
int queries[][2] = {{0, 2}, {3, 4}}; // given queries
int q = sizeof(queries) / sizeof(queries[0]); // number of queries
for (int i = 0; i < q; i++) {
cout << check(queries[i][0], queries[i][1]) << "\n";
}
return 0;
} आउटपुट
2 0
इस दृष्टिकोण में, हम उन प्रश्नों की गणना के लिए निरंतर समय ले रहे हैं जो हमारी समय जटिलता को O(N*Q) से काफी कम कर देते हैं। करने के लिए ओ(एन) , जहां N अब हमारे दिए गए सरणी का आकार है। यह प्रोग्राम उच्च बाधाओं के लिए भी काम कर सकता है।
उपरोक्त कोड की व्याख्या
n इस दृष्टिकोण से, हम सभी उपसर्ग बिट्स की गणना कर रहे हैं और इसे सूचकांक में संग्रहीत कर रहे हैं। अब जब हम प्रश्नों की गणना करते हैं, तो हमें केवल यह जांचने की आवश्यकता होती है कि क्या बिट की संख्या उतनी ही है जितनी कि सीमा में मौजूद तत्वों की संख्या है या नहीं। यदि हाँ, तो हम अपने x में इस बिट को 1 पर सेट करते हैं, और यदि नहीं, तो हम बिट को ऐसे छोड़ देते हैं जैसे दी गई सीमा में मौजूद किसी भी संख्या में वह बिट 0 है, इसलिए संपूर्ण बिटवाइज़ और उस बिट का शून्य होगा, और इस तरह हम बिटवाइज़ AND की गणना कर रहे हैं।
निष्कर्ष
इस लेख में, हम दिए गए सरणी के बिटवाइज़ और इंडेक्स रेंज [एल, आर] के लिए सभी प्रश्नों की गणना करने के लिए एक समस्या का समाधान करते हैं। हमने इस समस्या के लिए C++ प्रोग्राम और संपूर्ण दृष्टिकोण (सामान्य और कुशल) भी सीखा जिसके द्वारा हमने इस समस्या को हल किया। हम उसी प्रोग्राम को अन्य भाषाओं जैसे सी, जावा, पायथन और अन्य भाषाओं में लिख सकते हैं। हमें उम्मीद है कि आपको यह लेख मददगार लगा होगा।