Count elements which divide all numbers in range L-R
Given N numbers and Q queries, each query consists of L and R. Task is to write a program which prints the count of numbers which divides all numbers in the given 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> |
1 0
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; } |
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)
Please Login to comment...