Computer >> 컴퓨터 >  >> 프로그램 작성 >> C++

C++를 사용하여 비트 OR>=K가 있는 하위 배열의 수 찾기

<시간/>

이 기사에서는 C++에서 비트 단위 OR>=K가 있는 하위 배열의 수를 해결하는 방법에 대해 간략하게 설명합니다. 그래서 배열 arr[]와 정수 K가 있고 OR(bitwise or)이 K보다 크거나 같은 하위 배열의 수를 찾아야 합니다. 그래서 여기에 주어진 문제의 예가 있습니다 -

Input: arr[] = {1, 2, 3} K = 3
Output: 4

Bitwise OR of sub-arrays:
{1} = 1
{1, 2} = 3
{1, 2, 3} = 3
{2} = 2
{2, 3} = 3
{3} = 3
4 sub-arrays have bitwise OR ≥ 3
Input: arr[] = {3, 4, 5} K = 6
Output: 2

해결책을 찾기 위한 접근 방식

이제 우리는 C++를 사용하여 문제를 해결하기 위해 두 가지 다른 방법을 사용할 것입니다 -

브루트 포스

이 접근 방식에서 우리는 단순히 형성할 수 있는 모든 하위 배열을 살펴보고 OR이 K보다 크거나 같은지 확인할 것입니다. 그렇다면 우리는 우리의 대답을 증가시킬 것입니다.

예시

#include <bits/stdc++.h>
using namespace std;
int main(){
    int arr[] = {1, 2, 3}; // given array.
    int k = 3;
    int size = sizeof(arr) / sizeof(int); // the size of our array.
    int answer = 0; // the counter variable.
    for(int i = 0; i < size; i++){
        int bitwise = 0; // the variable that we compare to k.
        for(int j = i; j < size; j++){ // all the subarrays starting from i.
            bitwise = bitwise | arr[j];
            if(bitwise >= k) // if bitwise >= k increment answer.
               answer++;
        }
    }
    cout << answer << "\n";
    return 0;
}

출력

4

이 접근 방식은 매우 간단하지만 이 접근 방식은 더 높은 제약 조건과 마찬가지로 더 높은 제약 조건에 적합하지 않기 때문에 결점이 있습니다. 이 접근 방식의 시간 복잡성이 O(N*N)이므로 시간이 너무 많이 걸립니다. 여기서 N은 주어진 배열의 크기이므로 이제 효율적인 접근 방식을 사용합니다.

효율적인 접근

이 접근 방식에서 우리는 OR 연산자의 몇 가지 속성을 사용할 것입니다. 즉, 더 많은 숫자를 추가하더라도 절대 감소하지 않습니다. 범위 {i,j}를 포함하는 하위 배열은 K보다 많은 OR을 가지며 우리는 이 속성을 활용하여 코드를 개선합니다.

예시

#include <bits/stdc++.h>
#define N 1000
using namespace std;
int t[4*N];
void build(int* a, int v, int start, int end){ // segment tree building
    if(start == end){
       t[v] = a[start];
       return;
    }
    int mid = (start + end)/2;
    build(a, 2 * v, start, mid);
    build(a, 2 * v + 1, mid + 1, end);
    t[v] = t[2 * v] | t[2 * v + 1];
}
int query(int v, int tl, int tr, int l, int r){ // for processing our queries or subarrays.
    if (l > r)
       return 0;
    if(tl == l && tr == r)
       return t[v];
    int tm = (tl + tr)/2;
    int q1 = query(2*v, tl, tm, l, min(tm, r));
    int q2 = query((2*v)+1, tm+1, tr, max(tm+1, l), r);
    return q1 | q2;
}
int main(){
    int arr[] = {1, 2, 3}; // given array.
    int k = 3;
    int size = sizeof(arr) / sizeof(arr[0]); // the size of our array.
    int answer = 0; // the counter variable.
    build(arr, 1, 0, size - 1); // building segment tree.
    for(int i = 0; i < size; i++){
        int start = i, end = size-1;
        int ind = INT_MAX;
        while(start <= end){ // binary search
            int mid = (start + end) / 2;
            if(query(1, 0, size-1, i, mid) >= k){ // checking subarray.
               ind = min(mid, ind);
               end = mid - 1;
            }
            else
               start = mid + 1;
        }
        if(ind != INT_MAX) // if ind is changed then increment the answer.
            answer += size - ind;
    }
    cout << answer << "\n";
    return 0;
}

출력

4

이 접근 방식에서는 이진 검색 및 세그먼트 트리를 사용하여 시간 복잡성을 O(N*N)에서 O(Nlog(N))으로 줄이는 데 도움이 됩니다. , 아주 좋은 것입니다. 이제 이 프로그램은 이전 프로그램과 달리 더 큰 제약 조건에서도 작동할 수 있습니다.

결론

이 기사에서는 이진 검색 및 세그먼트 트리를 사용하여 O(nlog(n)) 시간 복잡도에서 OR>=K를 갖는 하위 배열의 수를 찾는 문제를 해결합니다. . 우리는 또한 이 문제에 대한 C++ 프로그램과 이 문제를 해결하는 완전한 접근 방식( Normal 및 Efficient)을 배웠습니다. C, Java, python 및 기타 언어와 같은 다른 언어로 동일한 프로그램을 작성할 수 있습니다. 이 기사가 도움이 되기를 바랍니다.