Open In App

Count 1s present in a range of indices [L, R] in a given array

Improve
Improve
Like Article
Like
Save
Share
Report

Given an array arr[] consisting of a single element N (1 ≤ N ≤ 106) and two integers L and R, ( 1 ≤ L ≤ R ≤ 105), the task is to make all array elements either 0 or 1 using the following operations :

  • Select an element P such that P > 1 from the array arr[].
  • Replace P with three elements at the same position, floor(P/2), P%2, floor(P/2) sequentially. Therefore, the size of the array arr[] increases by 2 after each operation.

Print the count of a total number of 1s in the range of indices [L, R] in the array arr[] after performing all the operations. 
Note: It is guaranteed that R is not greater than the length of the final array Arr.

Examples: 

Input: N = 7, L = 2, R = 5
Output: 4
Explanation: 
Step 1: arr[] = [7]. Selecting 7 modifies arr[] to {3, 1, 3}. 
Step 2: arr[] = [3, 1, 3]. Selecting 3 modifies arr[] to {1, 1, 1, 1, 3}. 
Step 3: arr[] = [1, 1, 1, 1, 3]. Selecting 3 modifies arr[] to {1, 1, 1, 1, 1, 1, 1} 
Therefore, all the indices in the range [2, 5] are filled with 1s. Therefore, count is 4.

Input: N = 7, L = 2, R = 2
Output: 1

 

Approach: Follow the steps below to solve the problem using Recursion:

  • Traverse the array.
  • Declare a function FindSize(N) to find the size of the modified array when the given array initially consists only of one element, i.e N.
  • Declare a function CountOnes(N) to calculate CountOnes(N / 2), N % 2 and CountOnes(N / 2) recursively.

Below is the implementation of the given approach : 

C++14




// C++ Program to implement
// the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to find the size of the
// array if the array initially
// contains a single element
int findSize(int N)
{
    // Base case
    if (N == 0)
        return 1;
    if (N == 1)
        return 1;
 
    int Size = 2 * findSize(N / 2) + 1;
 
    // P / 2 -> findSize(N / 2)
    // P % 2 -> 1
    // P / 2 -> findSize(N / 2)
    return Size;
}
 
// Function to return the count
// of 1s in the range [L, R]
int CountOnes(int N, int L, int R)
{
    if (L > R) {
        return 0;
    }
 
    // Base Case
    if (N <= 1) {
 
        return N;
    }
 
    int ret = 0;
    int M = N / 2;
    int Siz_M = findSize(M);
 
    // PART 1 -> N / 2
    // [1, Siz_M]
    if (L <= Siz_M) {
 
        // Update the right end point
        // of the range to min(Siz_M, R)
        ret += CountOnes(
            N / 2, L, min(Siz_M, R));
    }
 
    // PART 2 -> N % 2
    // [SizM + 1, Siz_M + 1]
    if (L <= Siz_M + 1 && Siz_M + 1 <= R) {
        ret += N % 2;
    }
 
    // PART 3 -> N / 2
    // [SizM + 2, 2 * Siz_M - 1]
    // Same as PART 1
    // Property of Symmetricity
    // Shift the coordinates according to PART 1
    // Subtract (Siz_M + 1) from both L, R
 
    if (Siz_M + 1 < R) {
        ret += CountOnes(N / 2,
                         max(1, L - Siz_M - 1),
                         R - Siz_M - 1);
    }
 
    return ret;
}
 
// Driver Code
int main()
{
    // Input
    int N = 7, L = 2, R = 5;
 
    // Counts the number of 1's in
    // the range [L, R]
    cout << CountOnes(N, L, R) << endl;
 
    return 0;
}


Java




// Java program to implement
// the above approach
import java.util.*;
class GFG
{
  
// Function to find the size of the
// array if the array initially
// contains a single element
static int findSize(int N)
{
     
    // Base case
    if (N == 0)
        return 1;
    if (N == 1)
        return 1;
    int Size = 2 * findSize(N / 2) + 1;
     
    // P / 2 -> findSize(N / 2)
    // P % 2 -> 1
    // P / 2 -> findSize(N / 2)
    return Size;
}
   
// Function to return the count
// of 1s in the range [L, R]
static int CountOnes(int N, int L, int R)
{
    if (L > R)
    {
        return 0;
    }
     
    // Base Case
    if (N <= 1)
    {
        return N;
    }  
    int ret = 0;
    int M = N / 2;
    int Siz_M = findSize(M);
   
    // PART 1 -> N / 2
    // [1, Siz_M]
    if (L <= Siz_M)
    {
         
        // Update the right end point
        // of the range to min(Siz_M, R)
        ret += CountOnes(N / 2, L,
                         Math.min(Siz_M, R));
    }
   
    // PART 2 -> N % 2
    // [SizM + 1, Siz_M + 1]
    if (L <= Siz_M + 1 && Siz_M + 1 <= R)
    {
        ret += N % 2;
    }
   
    // PART 3 -> N / 2
    // [SizM + 2, 2 * Siz_M - 1]
    // Same as PART 1
    // Property of Symmetricity
    // Shift the coordinates according to PART 1
    // Subtract (Siz_M + 1) from both L, R
    if (Siz_M + 1 < R)
    {
        ret += CountOnes(N / 2,
                         Math.max(1, L - Siz_M - 1),
                         R - Siz_M - 1);
    }
    return ret;
}
  
// Driver Code
public static void main(String[] args)
{
   
    // Input
    int N = 7, L = 2, R = 5;
     
    // Counts the number of 1's in
    // the range [L, R]
    System.out.println(CountOnes(N, L, R));
}
}
 
// This code is contributed by code_hunt.


Python3




# Python3 program to implement
# the above approach
 
# Function to find the size of the
# array if the array initially
# contains a single element
def findSize(N):
 
    # Base case
    if (N == 0):
        return 1
    if (N == 1):
        return 1
 
    Size = 2 * findSize(N // 2) + 1
 
    # P / 2 -> findSize(N // 2)
    # P % 2 -> 1
    # P / 2 -> findSize(N / 2)
    return Size
 
# Function to return the count
# of 1s in the range [L, R]
def CountOnes(N, L, R):
 
    if (L > R):
        return 0
 
    # Base Case
    if (N <= 1):
        return N
 
    ret = 0
    M = N // 2
    Siz_M = findSize(M)
 
    # PART 1 -> N / 2
    # [1, Siz_M]
    if (L <= Siz_M):
 
        # Update the right end point
        # of the range to min(Siz_M, R)
        ret += CountOnes(
            N // 2, L, min(Siz_M, R))
 
    # PART 2 -> N % 2
    # [SizM + 1, Siz_M + 1]
    if (L <= Siz_M + 1 and Siz_M + 1 <= R):
        ret += N % 2
 
    # PART 3 -> N / 2
    # [SizM + 2, 2 * Siz_M - 1]
    # Same as PART 1
    # Property of Symmetricity
    # Shift the coordinates according to PART 1
    # Subtract (Siz_M + 1) from both L, R
 
    if (Siz_M + 1 < R):
        ret += CountOnes(N // 2,
                         max(1, L - Siz_M - 1),
                         R - Siz_M - 1)
 
    return ret
 
# Driver Code
if __name__ == "__main__":
 
    # Input
    N = 7
    L = 2
    R = 5
 
    # Counts the number of 1's in
    # the range [L, R]
    print(CountOnes(N, L, R))
 
# This code is contributed by chitranayal


C#




// C# program to implement
// the above approach
using System;
 
class GFG{
 
// Function to find the size of the
// array if the array initially
// contains a single element
static int findSize(int N)
{
     
    // Base case
    if (N == 0)
        return 1;
    if (N == 1)
        return 1;
   
    int Size = 2 * findSize(N / 2) + 1;
     
    // P / 2 -> findSize(N / 2)
    // P % 2 -> 1
    // P / 2 -> findSize(N / 2)
    return Size;
}
   
// Function to return the count
// of 1s in the range [L, R]
static int CountOnes(int N, int L, int R)
{
    if (L > R)
    {
        return 0;
    }
     
    // Base Case
    if (N <= 1)
    {
        return N;
    }
   
    int ret = 0;
    int M = N / 2;
    int Siz_M = findSize(M);
   
    // PART 1 -> N / 2
    // [1, Siz_M]
    if (L <= Siz_M)
    {
         
        // Update the right end point
        // of the range to min(Siz_M, R)
        ret += CountOnes(N / 2, L,
                         Math.Min(Siz_M, R));
    }
   
    // PART 2 -> N % 2
    // [SizM + 1, Siz_M + 1]
    if (L <= Siz_M + 1 && Siz_M + 1 <= R)
    {
        ret += N % 2;
    }
   
    // PART 3 -> N / 2
    // [SizM + 2, 2 * Siz_M - 1]
    // Same as PART 1
    // Property of Symmetricity
    // Shift the coordinates according to PART 1
    // Subtract (Siz_M + 1) from both L, R
    if (Siz_M + 1 < R)
    {
        ret += CountOnes(N / 2,
                         Math.Max(1, L - Siz_M - 1),
                         R - Siz_M - 1);
    }
    return ret;
}
 
// Driver code
static void Main()
{
     
    // Input
    int N = 7, L = 2, R = 5;
     
    // Counts the number of 1's in
    // the range [L, R]
    Console.WriteLine(CountOnes(N, L, R));
}
}
 
// This code is contributed by divyesh072019


Javascript




<script>
 
    // Javascript program to implement
    // the above approach
     
    // Function to find the size of the
    // array if the array initially
    // contains a single element
    function findSize(N)
    {
 
        // Base case
        if (N == 0)
            return 1;
        if (N == 1)
            return 1;
 
        let Size = 2 *
                   findSize(parseInt(N / 2, 10)) + 1;
 
        // P / 2 -> findSize(N / 2)
        // P % 2 -> 1
        // P / 2 -> findSize(N / 2)
        return Size;
    }
 
    // Function to return the count
    // of 1s in the range [L, R]
    function CountOnes(N, L, R)
    {
        if (L > R)
        {
            return 0;
        }
 
        // Base Case
        if (N <= 1)
        {
            return N;
        }
 
        let ret = 0;
        let M = parseInt(N / 2, 10);
        let Siz_M = findSize(M);
 
        // PART 1 -> N / 2
        // [1, Siz_M]
        if (L <= Siz_M)
        {
 
            // Update the right end point
            // of the range to min(Siz_M, R)
            ret += CountOnes(parseInt(N / 2, 10), L,
            Math.min(Siz_M, R));
        }
 
        // PART 2 -> N % 2
        // [SizM + 1, Siz_M + 1]
        if (L <= Siz_M + 1 && Siz_M + 1 <= R)
        {
            ret += N % 2;
        }
 
        // PART 3 -> N / 2
        // [SizM + 2, 2 * Siz_M - 1]
        // Same as PART 1
        // Property of Symmetricity
        // Shift the coordinates according to PART 1
        // Subtract (Siz_M + 1) from both L, R
        if (Siz_M + 1 < R)
        {
            ret += CountOnes(parseInt(N / 2, 10),
            Math.max(1, L - Siz_M - 1), R - Siz_M - 1);
        }
        return ret;
    }
     
    // Input
    let N = 7, L = 2, R = 5;
      
    // Counts the number of 1's in
    // the range [L, R]
    document.write(CountOnes(N, L, R));
   
</script>


Output: 

4

 

Time Complexity: O(N) ( Using Master’s Theorem, T(N) = 2 * T(N / 2) + 1 => T(N) = O(N)) 
Auxiliary Space: O(N)

 



Last Updated : 23 Apr, 2021
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads