이 문제에서는 N개의 숫자와 정수 값 x로 구성된 배열 arr[]이 제공됩니다. 우리의 임무는 Binary Lifting을 사용하여 N개의 접두사 합에서 X보다 크거나 같은 첫 번째 요소를 찾는 프로그램을 만드는 것입니다. .
접두사 합계 배열 요소의 각 요소가 초기 배열의 해당 인덱스까지의 모든 요소의 합인 배열입니다.
예 - 배열[] ={5, 2, 9, 4, 1}
prefixSumArray[] ={5, 7, 16, 20, 21}
문제를 이해하기 위해 예를 들어 보겠습니다.
Input: arr[] = {5, 2, 9, 4, 1}, X = 19 Output: 3
솔루션 접근 방식
여기에서는 바이너리 리프팅 개념을 사용하여 문제를 해결할 것입니다. . Binary Lifting은 주어진 숫자의 값을 0에서 N 사이의 2승(비트를 뒤집음으로써 수행)으로 증가시키는 것입니다.
우리는 'P' 인덱스의 초기 값을 찾을 이진 트리를 들어올리는 것과 유사한 개념을 고려할 것입니다. 이것은 값이 X보다 크지 않도록 비트를 뒤집어서 증가합니다. 이제 이 위치 'P'와 함께 리프트를 고려할 것입니다.
이를 위해 i 번째 비트 플립이 합이 X보다 커지지 않도록 숫자의 비트를 뒤집기 시작할 것입니다. 이제 'P' -
값을 기반으로 하는 두 가지 경우가 있습니다.타겟 위치는 'position + 2^i 사이에 있습니다. ' 및 '위치 + 2^(i+1) ' 여기서 i번째 리프트는 값을 증가시켰습니다. 또는 대상 위치가 '위치 사이에 있습니다. ' 및 '위치 + 2^i '.
이를 사용하여 인덱스 위치를 고려할 것입니다.
예시
솔루션 작동을 설명하는 프로그램
#include <iostream> #include <math.h> using namespace std; void generatePrefixSum(int arr[], int prefSum[], int n){ prefSum[0] = arr[0]; for (int i = 1; i < n; i++) prefSum[i] = prefSum[i - 1] + arr[i]; } int findPreSumIndexBL(int prefSum[], int n, int x){ int P = 0; int LOGN = log2(n); if (x <= prefSum[0]) return 0; for (int i = LOGN; i >= 0; i--) { if (P + (1 << i) < n && prefSum[P + (1 << i)] < x) { P += (1 << i); } } return P + 1; } int main(){ int arr[] = { 5, 2, 9, 4, 1 }; int X = 19; int n = sizeof(arr) / sizeof(arr[0]); int prefSum[n] = { 0 }; generatePrefixSum(arr, prefSum, n); cout<<"The index of first elements of the array greater than the given number is "; cout<<findPreSumIndexBL(prefSum, n, X); return 0; }
출력
The index of first elements of the array greater than the given number is 3