Open In App

Count elements which divide all numbers in range L-R

Last Updated : 27 Apr, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

The problem statement describes a scenario where we are given an array of N numbers and Q queries. Each query consists of two integers L and R, representing a range of indices in the array. The task is to find the count of numbers in the array that divide all the numbers in the range L-R.

Examples : 

Input : a = {3, 4, 2, 2, 4, 6} 
        Q = 2
        L = 1 R = 4  
        L = 2 R = 6
Output :  0
          2 
Explanation : The range 1-4 has {3, 4, 2, 2} 
which does not have any number that divides all the 
numbers in this range. 
The range 2-6 has {4, 2, 2, 4, 6} which has  2 numbers {2, 2} which divides 
all numbers in the given range. 

Input: a = {1, 2, 3, 5} 
       Q = 2 
       L = 1 R = 4 
       L = 2 R = 4 
Output: 1 
        0      

Naive approach : Iterate from range L-R for every query and check if the given element at index-i divide all the numbers in the range. We keep a count for of all the elements which divides all the numbers. The complexity of every query at worst case will be O(n2).

Below is the implementation of Naive Approach :  

C++




// CPP program to Count elements which
// divides all numbers in range L-R
#include <bits/stdc++.h>
using namespace std;
 
// function to count element
// Time complexity O(n^2) worst case
int answerQuery(int a[], int n,
                int l, int r)
{
    // answer for query
    int count = 0;
 
    // 0 based index
    l = l - 1;
 
    // iterate for all elements
    for (int i = l; i < r; i++)
    {
        int element = a[i];
        int divisors = 0;
 
        // check if the element divides
        // all numbers in range
        for (int j = l; j < r; j++)
        {
            // no of elements
            if (a[j] % a[i] == 0)
                divisors++;
            else
                break;
        }
         
        // if all elements are divisible by a[i]
        if (divisors == (r - l))
            count++;
    }
 
    // answer for every query
    return count;
}
 
// Driver Code
int main()
{
    int a[] = { 1, 2, 3, 5 };
    int n = sizeof(a) / sizeof(a[0]);
 
    int l = 1, r = 4;
    cout << answerQuery(a, n, l, r) << endl;
 
    l = 2, r = 4;   
    cout << answerQuery(a, n, l, r) << endl;
    return 0;
}


Java




// Java program to Count elements which
// divides all numbers in range L-R
import java.io.*;
 
class GFG
{
 
// function to count element
// Time complexity O(n^2) worst case
static int answerQuery(int a[], int n,
                       int l, int r)
{
    // answer for query
    int count = 0;
 
    // 0 based index
    l = l - 1;
 
    // iterate for all elements
    for (int i = l; i < r; i++)
    {
        int element = a[i];
        int divisors = 0;
 
        // check if the element divides
        // all numbers in range
        for (int j = l; j < r; j++)
        {
            // no of elements
            if (a[j] % a[i] == 0)
                divisors++;
            else
                break;
        }
         
        // if all elements are divisible by a[i]
        if (divisors == (r - l))
            count++;
    }
 
    // answer for every query
    return count;
}
 
// Driver Code
public static void main (String[] args)
{
    int a[] = { 1, 2, 3, 5 };
    int n = a.length;
     
    int l = 1, r = 4;
    System.out.println( answerQuery(a, n, l, r));
     
    l = 2; r = 4;
    System.out.println( answerQuery(a, n, l, r));
}
}
 
// This code is contributed by anuj_67..


Python3




# Python 3 program to Count elements which
# divides all numbers in range L-R
 
# function to count element
# Time complexity O(n^2) worst case
def answerQuery(a, n, l, r):
     
    # answer for query
    count = 0
 
    # 0 based index
    l = l - 1
 
    # iterate for all elements
    for i in range(l, r, 1):
        element = a[i]
        divisors = 0
 
        # check if the element divides
        # all numbers in range
        for j in range(l, r, 1):
             
            # no of elements
            if (a[j] % a[i] == 0):
                divisors += 1
            else:
                break
         
        # if all elements are divisible
        # by a[i]
        if (divisors == (r - l)):
            count += 1
 
    # answer for every query
    return count
 
# Driver Code
if __name__ =='__main__':
    a = [1, 2, 3, 5]
    n = len(a)
 
    l = 1
    r = 4
    print(answerQuery(a, n, l, r))
 
    l = 2
    r = 4
    print(answerQuery(a, n, l, r))
 
# This code is contributed by
# Shashank_Sharma


C#




// C# program to Count elements which
// divides all numbers in range L-R
using System;
 
class GFG
{
 
// function to count element
// Time complexity O(n^2) worst case
static int answerQuery(int []a, int n,
                       int l, int r)
{
    // answer for query
    int count = 0;
 
    // 0 based index
    l = l - 1;
 
    // iterate for all elements
    for (int i = l; i < r; i++)
    {
        //int element = a[i];
        int divisors = 0;
 
        // check if the element divides
        // all numbers in range
        for (int j = l; j < r; j++)
        {
            // no of elements
            if (a[j] % a[i] == 0)
                divisors++;
            else
                break;
        }
         
        // if all elements are divisible by a[i]
        if (divisors == (r - l))
            count++;
    }
 
    // answer for every query
    return count;
}
 
// Driver Code
public static void Main ()
{
    int []a = { 1, 2, 3, 5 };
    int n = a.Length;
     
    int l = 1, r = 4;
    Console.WriteLine(answerQuery(a, n, l, r));
     
    l = 2; r = 4;
    Console.WriteLine(answerQuery(a, n, l, r));
}
}
 
// This code is contributed by anuj_67..


PHP




<?php
// PHP program to Count elements which
// divides all numbers in range L-R
 
// function to count element
// Time complexity O(n^2) worst case
function answerQuery($a, $n, $l, $r)
{
    // answer for query
    $count = 0;
 
    // 0 based index
    $l = $l - 1;
 
    // iterate for all elements
    for ($i = $l; $i < $r; $i++)
    {
        $element = $a[$i];
        $divisors = 0;
 
        // check if the element divides
        // all numbers in range
        for ($j = $l; $j < $r; $j++)
        {
            // no of elements
            if ($a[$j] % $a[$i] == 0)
                $divisors++;
            else
                break;
        }
         
        // if all elements are divisible by a[i]
        if ($divisors == ($r - $l))
            $count++;
    }
 
    // answer for every query
    return $count;
}
 
// Driver Code
$a = array(1, 2, 3, 5);
$n = sizeof($a);
 
$l = 1; $r = 4;
echo answerQuery($a, $n, $l, $r) . "\n";
 
$l = 2; $r = 4;
echo answerQuery($a, $n, $l, $r) . "\n";
 
// This code is contributed
// by Akanksha Rai


Javascript




<script>
// javascript program to Count elements which
// divides all numbers in range L-R
 
    // function to count element
    // Time complexity O(n^2) worst case
    function answerQuery(a , n , l , r)
    {
     
        // answer for query
        var count = 0;
 
        // 0 based index
        l = l - 1;
 
        // iterate for all elements
        for (i = l; i < r; i++) {
            var element = a[i];
            var divisors = 0;
 
            // check if the element divides
            // all numbers in range
            for (j = l; j < r; j++) {
                // no of elements
                if (a[j] % a[i] == 0)
                    divisors++;
                else
                    break;
            }
 
            // if all elements are divisible by a[i]
            if (divisors == (r - l))
                count++;
        }
 
        // answer for every query
        return count;
    }
 
    // Driver Code
        var a = [ 1, 2, 3, 5 ];
        var n = a.length;
 
        var l = 1, r = 4;
        document.write(answerQuery(a, n, l, r)+"<br/>");
 
        l = 2;
        r = 4;
        document.write(answerQuery(a, n, l, r));
 
// This code is contributed by gauravrajput1
</script>


Output

1
0

Time Complexity:-The time complexity of the given Java program is O(n^2) in the worst case, where n is the length of the input array. This is because the program has two nested loops, each iterating over the input array, resulting in a time complexity of O(n^2) for the worst case.

Space Complexity:-The space complexity of the program is O(1), which means that the amount of memory used by the program is constant, regardless of the input size. This is because the program only uses a fixed amount of memory for storing variables and does not create any new data structures or objects that grow in size with the input size.

Efficient approach : 

Use Segment Trees to solve this problem. If an element divides all the numbers in a given range, then the element is the minimum number in that range and it is the gcd of all elements in the given range L-R. So the count of the number of minimums in range L-R, given that minimum is equal to the gcd of that range will be our answer to every query. The problem boils down to finding the GCD, MINIMUM and countMINIMUM for every range using Segment trees. On every node of the tree, three values are stored. 

On querying for a given range, if the gcd and minimum of the given range are equal, countMINIMUM is returned as the answer. If they are unequal, 0 is returned as the answer.

Below is the implementation of efficient approach : 

C++




// CPP program to Count elements
// which divides all numbers in
// range L-R efficient approach
#include <bits/stdc++.h>
using namespace std;
 
#define N 100005
 
// predefines the tree with nodes
// storing gcd, min and count
struct node
{
    int gcd;
    int min;
    int cnt;
} tree[5 * N];
 
// function to construct the tree
void buildtree(int low, int high,
               int pos, int a[])
{
    // base condition
    if (low == high)
    {
        // initially always gcd and min
        // are same at leaf node
        tree[pos].min =  tree[pos].gcd = a[low];
        tree[pos].cnt = 1;
         
        return;
    }
 
    int mid = (low + high) >> 1;
     
    // left-subtree
    buildtree(low, mid, 2 * pos + 1, a);
 
    // right-subtree
    buildtree(mid + 1, high, 2 * pos + 2, a);
 
    // finds gcd of left and right subtree
    tree[pos].gcd = __gcd(tree[2 * pos + 1].gcd,
                      tree[2 * pos + 2].gcd);
 
    // left subtree has the minimum element
    if (tree[2 * pos + 1].min < tree[2 * pos + 2].min)
    {
        tree[pos].min = tree[2 * pos + 1].min;
        tree[pos].cnt = tree[2 * pos + 1].cnt;
    }
     
    // right subtree has the minimum element
    else
    if (tree[2 * pos + 1].min > tree[2 * pos + 2].min)
    {
        tree[pos].min = tree[2 * pos + 2].min;
        tree[pos].cnt = tree[2 * pos + 2].cnt;
    }
     
    // both subtree has the same minimum element
    else
    {
        tree[pos].min = tree[2 * pos + 1].min;
        tree[pos].cnt = tree[2 * pos + 1].cnt +
                        tree[2 * pos + 2].cnt;
    }
}
 
// function that answers every query
node query(int s, int e, int low, int high, int pos)
{
    node dummy;
     
    // out of range
    if (e < low or s > high)
    {
        dummy.gcd = dummy.min = dummy.cnt = 0;
        return dummy;
    }
     
    // in range
    if (s >= low and e <= high)
    {
        node dummy;
        dummy.gcd = tree[pos].gcd;
        dummy.min = tree[pos].min;
        if (dummy.gcd != dummy.min)
            dummy.cnt = 0;
        else
            dummy.cnt = tree[pos].cnt;
         
        return dummy;
    }
 
    int mid = (s + e) >> 1;
     
    // left-subtree
    node ans1 = query(s, mid, low,
                high, 2 * pos + 1);
     
    // right-subtree
    node ans2 = query(mid + 1, e, low,
                   high, 2 * pos + 2);
 
    node ans;
     
    // when both left subtree and
    // right subtree is in range
    if (ans1.gcd and ans2.gcd)
    {
        // merge two trees
        ans.gcd = __gcd(ans1.gcd, ans2.gcd);
        ans.min = min(ans1.min, ans2.min);
 
        // when gcd is not equal to min
        if (ans.gcd != ans.min)        
            ans.cnt = 0;       
        else
        {
            // add count when min is
            // same of both subtree
            if (ans1.min == ans2.min)            
                ans.cnt = ans2.cnt + ans1.cnt;           
             
            // store the minimal's count
            else
            if (ans1.min < ans2.min)            
                ans.cnt = ans1.cnt;           
            else            
                ans.cnt = ans2.cnt;           
        }
         
        return ans;
    }
     
    // only left subtree is in range
    else if (ans1.gcd)
        return ans1;
     
    // only right subtree is in range
    else if (ans2.gcd)
        return ans2;
}
 
// function to answer query in range l-r
int answerQuery(int a[], int n, int l, int r)
{
    // calls the function which returns
    // a node this function returns the
    // count which will be the answer
    return query(0, n - 1, l - 1, r - 1, 0).cnt;
}
 
// Driver Code
int main()
{
    int a[] = { 3, 4, 2, 2, 4, 6 };
 
    int n = sizeof(a) / sizeof(a[0]);
    buildtree(0, n - 1, 0, a);
    int l = 1, r = 4;
 
    // answers 1-st query
    cout << answerQuery(a, n, l, r) << endl;
 
    l = 2, r = 6;
    // answers 2nd query
    cout << answerQuery(a, n, l, r) << endl;
    return 0;
}


Java




// Java program to Count elements which divides all numbers
// in range L-R efficient approach
import java.io.*;
 
// predefines the tree with nodes storing gcd, min and count
class Node {
  int gcd;
  int min;
  int cnt;
}
 
class GFG {
 
  static final int N = 100005;
  static Node[] tree = new Node[5 * N];
 
  // function to construct the tree
  static void buildtree(int low, int high, int pos,
                        int[] a)
  {
    // base condition
    if (low == high) {
      // initially always gcd and min
      // are same at leaf node
      tree[pos] = new Node();
      tree[pos].min = tree[pos].gcd = a[low];
      tree[pos].cnt = 1;
      return;
    }
 
    int mid = (low + high) >> 1;
 
    // left-subtree
    buildtree(low, mid, 2 * pos + 1, a);
 
    // right-subtree
    buildtree(mid + 1, high, 2 * pos + 2, a);
 
    // finds gcd of left and right subtree
    tree[pos] = new Node();
    tree[pos].gcd = gcd(tree[2 * pos + 1].gcd,
                        tree[2 * pos + 2].gcd);
 
    // left subtree has the minimum element
    if (tree[2 * pos + 1].min < tree[2 * pos + 2].min) {
      tree[pos].min = tree[2 * pos + 1].min;
      tree[pos].cnt = tree[2 * pos + 1].cnt;
    }
 
    // right subtree has the minimum element
    else if (tree[2 * pos + 1].min
             > tree[2 * pos + 2].min) {
      tree[pos].min = tree[2 * pos + 2].min;
      tree[pos].cnt = tree[2 * pos + 2].cnt;
    }
 
    // both subtree has the same minimum element
    else {
      tree[pos].min = tree[2 * pos + 1].min;
      tree[pos].cnt = tree[2 * pos + 1].cnt
        + tree[2 * pos + 2].cnt;
    }
  }
 
  // Helper function to calculate GCD of two integers
  static int gcd(int a, int b)
  {
    return b == 0 ? a : gcd(b, a % b);
  }
 
  // Function that answers every query
  static Node query(int s, int e, int low, int high,
                    int pos, Node[] tree)
  {
    Node dummy = new Node();
 
    // out of range
    if (e < low || s > high) {
      dummy.gcd = dummy.min = dummy.cnt = 0;
      return dummy;
    }
 
    // in range
    if (s >= low && e <= high) {
      Node result = new Node();
      result.gcd = tree[pos].gcd;
      result.min = tree[pos].min;
      if (result.gcd != result.min)
        result.cnt = 0;
      else
        result.cnt = tree[pos].cnt;
 
      return result;
    }
 
    int mid = (s + e) >> 1;
 
    // left-subtree
    Node ans1
      = query(s, mid, low, high, 2 * pos + 1, tree);
 
    // right-subtree
    Node ans2 = query(mid + 1, e, low, high,
                      2 * pos + 2, tree);
 
    Node ans = new Node();
 
    // when both left subtree and right subtree is in
    // range
    if (ans1.gcd != 0 && ans2.gcd != 0) {
      // merge two trees
      ans.gcd = gcd(ans1.gcd, ans2.gcd);
      ans.min = Math.min(ans1.min, ans2.min);
 
      // when gcd is not equal to min
      if (ans.gcd != ans.min)
        ans.cnt = 0;
      else {
        // add count when min is same of both
        // subtree
        if (ans1.min == ans2.min)
          ans.cnt = ans2.cnt + ans1.cnt;
        // store the minimal's count
        else if (ans1.min < ans2.min)
          ans.cnt = ans1.cnt;
        else
          ans.cnt = ans2.cnt;
      }
 
      return ans;
    }
 
    // only left subtree is in range
    else if (ans1.gcd != 0)
      return ans1;
 
    // only right subtree is in range
    else if (ans2.gcd != 0)
      return ans2;
 
    return dummy;
  }
 
  // function to answer query in range l-r
  static int answerQuery(int[] a, int n, int l, int r,
                         Node[] tree)
  {
    // calls the function which returns a node this
    // function returns the count which will be the
    // answer
    return query(0, n - 1, l - 1, r - 1, 0, tree).cnt;
  }
 
  public static void main(String[] args)
  {
    int a[] = { 3, 4, 2, 2, 4, 6 };
 
    int n = a.length;
    buildtree(0, n - 1, 0, a);
    int l = 1, r = 4;
 
    // answers 1-st query
    System.out.println(answerQuery(a, n, l, r, tree));
 
    l = 2;
    r = 6;
    // answers 2nd query
    System.out.println(answerQuery(a, n, l, r, tree));
  }
}
 
// This code is contributed by sankar.


Python3




# Python program to count elements which divide all numbers
# in range L-R efficient approach
 
# predefines the tree with nodes storing gcd, min and count
class Node:
    def __init__(self):
        self.gcd = 0
        self.min = 0
        self.cnt = 0
 
 
def buildtree(low, high, pos, a, tree):
    # base condition
    if low == high:
        # initially always gcd and min are same at leaf node
        tree[pos] = Node()
        tree[pos].min = tree[pos].gcd = a[low]
        tree[pos].cnt = 1
        return
 
    mid = (low + high) >> 1
 
    # left-subtree
    buildtree(low, mid, 2 * pos + 1, a, tree)
 
    # right-subtree
    buildtree(mid + 1, high, 2 * pos + 2, a, tree)
 
    # finds gcd of left and right subtree
    tree[pos] = Node()
    tree[pos].gcd = gcd(tree[2 * pos + 1].gcd, tree[2 * pos + 2].gcd)
 
    # left subtree has the minimum element
    if tree[2 * pos + 1].min < tree[2 * pos + 2].min:
        tree[pos].min = tree[2 * pos + 1].min
        tree[pos].cnt = tree[2 * pos + 1].cnt
 
    # right subtree has the minimum element
    elif tree[2 * pos + 1].min > tree[2 * pos + 2].min:
        tree[pos].min = tree[2 * pos + 2].min
        tree[pos].cnt = tree[2 * pos + 2].cnt
 
    # both subtree has the same minimum element
    else:
        tree[pos].min = tree[2 * pos + 1].min
        tree[pos].cnt = tree[2 * pos + 1].cnt + tree[2 * pos + 2].cnt
 
# Helper function to calculate GCD of two integers
def gcd(a, b):
    return a if b == 0 else gcd(b, a % b)
 
# Function that answers every query
def query(s, e, low, high, pos, tree):
    dummy = Node()
 
    # out of range
    if e < low or s > high:
        dummy.gcd = dummy.min = dummy.cnt = 0
        return dummy
 
    # in range
    if s >= low and e <= high:
        result = Node()
        result.gcd = tree[pos].gcd
        result.min = tree[pos].min
        if result.gcd != result.min:
            result.cnt = 0
        else:
            result.cnt = tree[pos].cnt
        return result
 
    mid = (s + e) >> 1
 
    # left-subtree
    ans1 = query(s, mid, low, high, 2 * pos + 1, tree)
 
    # right-subtree
    ans2 = query(mid + 1, e, low, high, 2 * pos + 2, tree)
 
    ans = Node()
 
    # when both left subtree and right subtree is in range
    if ans1.gcd != 0 and ans2.gcd != 0:
        # merge two trees
        ans.gcd = gcd(ans1.gcd, ans2.gcd)
        ans.min = min(ans1.min, ans2.min)
 
        # when gcd is not equal to min
        if ans.gcd != ans.min:
            ans.cnt = 0
        else:
            # add count when min is same of both subtree
            if ans1.min == ans2.min:
                ans.cnt = ans2.cnt + ans1.cnt
            # store the minimal's count
            elif ans1.min < ans2.min:
                ans.cnt = ans1.cnt
            else:
                ans.cnt = ans2.cnt
 
        return ans
 
    # only left subtree is in range
    elif ans1.gcd != 0:
        return ans1
 
    # only right subtree is in range
    elif ans2.gcd != 0:
        return ans2
 
    return dummy
 
# Function to answer query in range l-r
def answerQuery(a, n, l, r, tree):
    # calls the function which returns a node this function
    # returns the count which will be the answer
    return query(0, n - 1, l - 1, r - 1, 0, tree).cnt
 
 
a = [3, 4, 2, 2, 4, 6]
 
n = len(a)
tree = [None] * (5 * n)
buildtree(0, n - 1, 0, a, tree)
l, r = 1, 4
 
# answers 1st query
print(answerQuery(a, n, l, r, tree))
 
l, r = 2, 6
# answers 2nd query
print(answerQuery(a, n, l, r, tree))
 
# This code is contributed by karthik.


C#




// C# program to Count elements which divides all numbers in
// range L-R efficient approach
 
using System;
 
// predefines the tree with nodes storing gcd, min and count
public class Node {
    public int gcd;
    public int min;
    public int cnt;
}
 
public class GFG {
 
    static int N = 100005;
    static Node[] tree = new Node[5 * N];
 
    // function to construct the tree
    static void buildtree(int low, int high, int pos,
                          int[] a)
    {
        // base condition
        if (low == high) {
            // initially always gcd and min
            // are same at leaf node
            tree[pos] = new Node();
            tree[pos].min = tree[pos].gcd = a[low];
            tree[pos].cnt = 1;
            return;
        }
 
        int mid = (low + high) >> 1;
 
        // left-subtree
        buildtree(low, mid, 2 * pos + 1, a);
 
        // right-subtree
        buildtree(mid + 1, high, 2 * pos + 2, a);
 
        // finds gcd of left and right subtree
        tree[pos] = new Node();
        tree[pos].gcd = gcd(tree[2 * pos + 1].gcd,
                            tree[2 * pos + 2].gcd);
 
        // left subtree has the minimum element
        if (tree[2 * pos + 1].min < tree[2 * pos + 2].min) {
            tree[pos].min = tree[2 * pos + 1].min;
            tree[pos].cnt = tree[2 * pos + 1].cnt;
        }
 
        // right subtree has the minimum element
        else if (tree[2 * pos + 1].min
                 > tree[2 * pos + 2].min) {
            tree[pos].min = tree[2 * pos + 2].min;
            tree[pos].cnt = tree[2 * pos + 2].cnt;
        }
 
        // both subtree has the same minimum element
        else {
            tree[pos].min = tree[2 * pos + 1].min;
            tree[pos].cnt = tree[2 * pos + 1].cnt
                            + tree[2 * pos + 2].cnt;
        }
    }
 
    // Helper function to calculate GCD of two integers
    static int gcd(int a, int b)
    {
        return b == 0 ? a : gcd(b, a % b);
    }
 
    // Function that answers every query
    static Node query(int s, int e, int low, int high,
                      int pos, Node[] tree)
    {
        Node dummy = new Node();
 
        // out of range
        if (e < low || s > high) {
            dummy.gcd = dummy.min = dummy.cnt = 0;
            return dummy;
        }
 
        // in range
        if (s >= low && e <= high) {
            Node result = new Node();
            result.gcd = tree[pos].gcd;
            result.min = tree[pos].min;
            if (result.gcd != result.min)
                result.cnt = 0;
            else
                result.cnt = tree[pos].cnt;
 
            return result;
        }
 
        int mid = (s + e) >> 1;
 
        // left-subtree
        Node ans1
            = query(s, mid, low, high, 2 * pos + 1, tree);
 
        // right-subtree
        Node ans2 = query(mid + 1, e, low, high,
                          2 * pos + 2, tree);
 
        Node ans = new Node();
 
        // when both left subtree and right subtree is in
        // range
        if (ans1.gcd != 0 && ans2.gcd != 0) {
            // merge two trees
            ans.gcd = gcd(ans1.gcd, ans2.gcd);
            ans.min = Math.Min(ans1.min, ans2.min);
 
            // when gcd is not equal to min
            if (ans.gcd != ans.min)
                ans.cnt = 0;
            else {
                // add count when min is same of both
                // subtree
                if (ans1.min == ans2.min)
                    ans.cnt = ans2.cnt + ans1.cnt;
                // store the minimal's count
                else if (ans1.min < ans2.min)
                    ans.cnt = ans1.cnt;
                else
                    ans.cnt = ans2.cnt;
            }
 
            return ans;
        }
 
        // only left subtree is in range
        else if (ans1.gcd != 0)
            return ans1;
 
        // only right subtree is in range
        else if (ans2.gcd != 0)
            return ans2;
 
        return dummy;
    }
 
    // function to answer query in range l-r
    static int answerQuery(int[] a, int n, int l, int r,
                           Node[] tree)
    {
        // calls the function which returns a node this
        // function returns the count which will be the
        // answer
        return query(0, n - 1, l - 1, r - 1, 0, tree).cnt;
    }
 
    static public void Main()
    {
 
        // Code
        int[] a = { 3, 4, 2, 2, 4, 6 };
 
        int n = a.Length;
        buildtree(0, n - 1, 0, a);
        int l = 1, r = 4;
 
        // answers 1-st query
        Console.WriteLine(answerQuery(a, n, l, r, tree));
 
        l = 2;
        r = 6;
        // answers 2nd query
        Console.WriteLine(answerQuery(a, n, l, r, tree));
    }
}
 
// This code is contributed by karthik.


Javascript




<script>
 
// JavaScript program to Count elements which divides
// all numbers in range L-R efficient approach
 
// predefines the tree with nodes storing gcd, min and count
class Node {
  constructor() {
    this.gcd = 0;
    this.min = 0;
    this.cnt = 0;
  }
}
 
const N = 100005;
const tree = new Array(5 * N).fill(null).map(() => new Node());
 
// function to construct the tree
function buildtree(low, high, pos, a) {
  // base condition
  if (low == high) {
    // initially always gcd and min are same at leaf node
    tree[pos].min = tree[pos].gcd = a[low];
    tree[pos].cnt = 1;
    return;
  }
 
  const mid = (low + high) >> 1;
 
  // left-subtree
  buildtree(low, mid, 2 * pos + 1, a);
 
  // right-subtree
  buildtree(mid + 1, high, 2 * pos + 2, a);
 
  // finds gcd of left and right subtree
  tree[pos] = new Node();
  tree[pos].gcd = gcd(tree[2 * pos + 1].gcd, tree[2 * pos + 2].gcd);
 
  // left subtree has the minimum element
  if (tree[2 * pos + 1].min < tree[2 * pos + 2].min) {
    tree[pos].min = tree[2 * pos + 1].min;
    tree[pos].cnt = tree[2 * pos + 1].cnt;
  }
 
  // right subtree has the minimum element
  else if (tree[2 * pos + 1].min > tree[2 * pos + 2].min) {
    tree[pos].min = tree[2 * pos + 2].min;
    tree[pos].cnt = tree[2 * pos + 2].cnt;
  }
 
  // both subtree has the same minimum element
  else {
    tree[pos].min = tree[2 * pos + 1].min;
    tree[pos].cnt = tree[2 * pos + 1].cnt + tree[2 * pos + 2].cnt;
  }
}
 
// Helper function to calculate GCD of two integers
function gcd(a, b) {
  return b == 0 ? a : gcd(b, a % b);
}
 
// Function that answers every query
function query(s, e, low, high, pos) {
  const dummy = new Node();
 
  // out of range
  if (e < low || s > high) {
    dummy.gcd = dummy.min = dummy.cnt = 0;
    return dummy;
  }
 
  // in range
  if (s >= low && e <= high) {
    const result = new Node();
    result.gcd = tree[pos].gcd;
    result.min = tree[pos].min;
    if (result.gcd != result.min) result.cnt = 0;
    else result.cnt = tree[pos].cnt;
 
    return result;
  }
 
  const mid = (s + e) >> 1;
 
  // left-subtree
  const ans1 = query(s, mid, low, high, 2 * pos + 1);
 
  // right-subtree
  const ans2 = query(mid + 1, e, low, high, 2 * pos + 2);
 
  const ans = new Node();
 
  // when both left subtree and right subtree is in range
  if (ans1.gcd != 0 && ans2.gcd != 0) {
    // merge two trees
    ans.gcd = gcd(ans1.gcd, ans2.gcd);
    ans.min = Math.min(ans1.min, ans2.min);
     
    // when gcd is not equal to min
    if (ans.gcd != ans.min) {
        ans.cnt = 0;
    }
    else {
        // add count when min is same of both subtree
        if (ans1.min === ans2.min) {
            ans.cnt = ans2.cnt + ans1.cnt;
        }
        // store the minimal's count
        else if (ans1.min < ans2.min) {
            ans.cnt = ans1.cnt;
        }
        else {
            ans.cnt = ans2.cnt;
        }
    }
     
    return ans;
  }
   
  // only left subtree is in range.
  else if (ans1.gcd != 0) {
    return ans1;
  }
   
  // only right subtree is in range
  else if (ans2.gcd != 0) {
    return ans2;
  }
   
  return dummy;
}
 
// function to answer query in range l-r
function answerQuery(a, n, l, r, tree) {
  // Calls the function which returns a node this function
  // returns the count which will be the answer.
  return query(0, n-1, l-1, r-1, 0, tree).cnt;
}
 
var a = [3, 4, 2, 2, 4, 6];
var n = a.length;
buildtree(0, n-1, 0, a);
var l = 1, r = 4;
 
// answers 1st query
document.write(answerQuery(a, n, l, r, tree) + "<br>");
 
l = 2;
r = 6;
// answers 2nd query
document.write(answerQuery(a, n, l, r, tree));
 
// This code is contributed by karthik.
 
</script>


Output

0
2

Time Complexity: Time Complexity for tree construction is O(n logn) since tree construction takes O(n) and finding out gcd takes O(log n). The time taken for every query in worst case will be O(log n * log n) since the inbuilt function __gcd takes O(log n)

Space Complexity: O(n)



Similar Reads

Count of arrays in which all adjacent elements are such that one of them divide the another
Given two positive integer n and n. The task is to find the number of arrays of size n that can be formed such that : Each element is in range [1, m]All adjacent element are such that one of them divide the another i.e element Ai divides Ai + 1 or Ai + 1 divides Ai + 2. Examples: Input : n = 3, m = 3. Output : 17 {1,1,1}, {1,1,2}, {1,1,3}, {1,2,1},
9 min read
Count array elements that divide the sum of all other elements
Given an array arr[], the task is to count the number of elements from the array which divide the sum of all other elements. Examples: Input: arr[] = {3, 10, 4, 6, 7} Output: 3 3 divides (10 + 4 + 6 + 7) i.e. 27 10 divides (3 + 4 + 6 + 7) i.e. 20 6 divides (3 + 10 + 4 + 7) i.e. 24 Input: arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} Output: 2 Naive Appro
10 min read
Queries to count numbers from given range which are divisible by all its digits
Given a 2D array arr[][] with each row of the form of a query { L, R }, the task is to count the numbers in the range [L, R] such that the number is divisible by all of its non-zero digit. Examples: Input: arr[][] ={ {1, 5}, {12, 14} } Output: 5 1 Explanation: Query1: All the numbers in the range [1, 5] are divisible by their digits. Query2: Number
8 min read
Find the element before which all the elements are smaller than it, and after which all are greater
Given an array, find an element before which all elements are smaller than it, and after which all are greater than it. Return the index of the element if there is such an element, otherwise, return -1. Examples: Input: arr[] = {5, 1, 4, 3, 6, 8, 10, 7, 9}; Output: 4 Explanation: All elements on left of arr[4] are smaller than it and all elements o
23 min read
Find all numbers that divide maximum array elements
Given an array of N numbers, the task is to print all the numbers greater than 1 which divides the maximum of array elements. Examples: Input: a[] = {6, 6, 12, 18, 13} Output: 2 3 6 All the numbers divide the maximum of array elements i.e., 4 Input: a[] = {12, 15, 27, 20, 40} Output: 2 3 4 5 Approach: Use hashing to store the count of all the facto
7 min read
Count of integers that divide all the elements of the given array
Given an array arr[] of N elements. The task is to find the count of positive integers that divide all the array elements. Examples: Input: arr[] = {2, 8, 10, 6} Output: 2 1 and 2 are the only integers that divide all the elements of the given array. Input: arr[] = {6, 12, 18, 12, 6} Output: 4 Approach: We know that the maximum integer that will di
5 min read
Count digits in given number N which divide N
Given a number N which may be 10^5 digits long, the task is to count all the digits in N which divide N. Divisibility by 0 is not allowed. If any digit in N which is repeated divides N, then all repetitions of that digit should be counted i. e., N = 122324, here 2 divides N and it appears 3 times. So count for digit 2 will be 3.Examples: Input : N
17 min read
Maximum number which can divide all array element after one replacement
Given an array arr, replace any one element in array with any other integer. The task is to return the maximum number which divides all elements in this array completely. Examples: Input: arr = [15, 9, 3]Output: 3Explanation: Here replace 15 with 3 so array becomes arr = [3, 9, 3] and now all elements in array are divisible by 3, so 3 is our answer
7 min read
Count numbers which are divisible by all the numbers from 2 to 10
Given an integer N, the task is to find the count of numbers from 1 to N which are divisible by all the numbers from 2 to 10. Examples: Input: N = 3000 Output: 1 2520 is the only number below 3000 which is divisible by all the numbers from 2 to 10. Input: N = 2000 Output: 0 Approach: Let's factorize numbers from 2 to 10. 2 = 2 3 = 3 4 = 22 5 = 5 6
3 min read
Generate a random permutation of elements from range [L, R] (Divide and Conquer)
Given a range [L, R] where L ? R, the task is to generate a random permutation of the sequence [L, L + 1, L + 2, ..., R].Examples: Input: L = 5, R = 15 Output: 11 9 6 5 8 7 10 12 13 15 14Input: L = 10, R = 20 Output: 16 14 11 10 13 12 15 17 18 20 19 Approach: We will use Divide and Conquer algorithm for our solution. We will create a global vector
7 min read