Given an array of n elements, the task is to find the fibonacci sum of a subset of the array where every element of the subset <= k.
Precisely, find F(Ai1) + F(Ai2) + F(Ai3) + … + F(Aix)), where (Ai1, Ai2, …, Aix) <= K and 1 <= (i1, i2, …, ix) <= n. Here, F(i) is the ith Fibonacci number
Examples :
Input : arr = {1, 2, 3, 4, 2, 7} Query 1 : K = 2 Query 2 : K = 6 Output : 3 8
Explanation :
In Query 1, the subset {1, 2, 2} is such a subset where all the elements in the subset are <= k i.e <= 2 in this case. The Fibonacci sum of the subset = F(1) + F(2) + F(2) = 1 + 1 + 1 = 3
In Query 2, the subset {1, 2, 3, 4, 2} is such a subset where all the elements in the subset are <= k i.e <= 6 in this case. The Fibonacci sum of the subset = F(1) + F(2) + F(3) + F(4) + F(2) = 1 + 1 + 2 + 3 + 1 = 8
Solve this using two different querying techniques, namely :
- Online Querying,
- Offline Querying
In both these methods, the only common step is the generation of the nth Fibonacci number.For an efficient technique to generate the nth Fibonacci number using this.
This method of generating the Fibonacci numbers is common to both querying techniques. Now, look at how to use these Fibonacci numbers that are generated using each of these two techniques.
Method 1 (Online Querying) :
In this technique, process the queries as they arrive. First of all, sort the array in increasing order. After getting a query for a particular k, use binary search on this sorted array to find the last index where the value of the array is & <= k. Let’s call this position x.
Now, since the array is sorted,
For all i <= x, a[i] <= x i.e a[i] <= a[x] for all i ∈ [1, x]
So, the subset to focus at is A1, A2, A3, ….Ax in the sorted array A, and Fibonacci sum is : F(A1)+F(A2)+F(A3)+…+F(Ax)
Use Prefix sum arrays to efficiently find the sum of the subset A1, A2, A3, ….Ax.
If prefixFibSum[i] stores the Fibonacci sum till the ith index of the sorted array A, then, the Fibonacci sum of subset of the array from 1 to x, is prefixFibSum[x]
Thus, Fibonacci Sum of Subset[1…x] = prefixFibSum[x], prefixFibSum[x] can be calculated as follows :
prefixFibSum[x] = prefixFibSum[x – 1] + A[x]th Fibonacci number, where, A[x] is the array element at xth index of the array.
Implementation:
C++
// C++ program to find fibonacci sum of // subarray where all elements <= k #include <bits/stdc++.h> using namespace std; // Helper function that multiplies 2 matrices // F and M of size 2*2, and puts the multiplication // result back to F[][] void multiply( int F[2][2], int M[2][2]) { int x = F[0][0] * M[0][0] + F[0][1] * M[1][0]; int y = F[0][0] * M[0][1] + F[0][1] * M[1][1]; int z = F[1][0] * M[0][0] + F[1][1] * M[1][0]; int w = F[1][0] * M[0][1] + F[1][1] * M[1][1]; F[0][0] = x; F[0][1] = y; F[1][0] = z; F[1][1] = w; } /* Helper function that calculates F[][] raise to the power n and puts the result in F[][] */ void power( int F[2][2], int n) { int i; int M[2][2] = { { 1, 1 }, { 1, 0 } }; // n - 1 times multiply the // matrix to {{1, 0}, {0, 1}} for (i = 2; i <= n; i++) multiply(F, M); } // Returns the nth fibonacci number int fib( int n) { int F[2][2] = { { 1, 1 }, { 1, 0 } }; if (n == 0) return 0; power(F, n - 1); return F[0][0]; } int findLessThanK( int arr[], int n, int k) { // find first index which is > k // using lower_bound return (lower_bound(arr, arr + n, k + 1) - arr); } // Function to build Prefix Fibonacci Sum int * buildPrefixFibonacciSum( int arr[], int n) { // Allocate memory to prefix // fibonacci sum array int * prefixFibSum = new int [n]; // Traverse the array from 0 to n - 1, // when at the ith index then we calculate // the a[i]th fibonacci number and calculate // the fibonacci sum till the ith index as // the sum of fibonacci sum till index i - 1 // and the a[i]th fibonacci number for ( int i = 0; i < n; i++) { int currFibNumber = fib(arr[i]); if (i == 0) { prefixFibSum[i] = currFibNumber; } else { prefixFibSum[i] = prefixFibSum[i - 1] + currFibNumber; } } return prefixFibSum; } // Return the answer for each query int processQuery( int arr[], int prefixFibSum[], int n, int k) { // index stores the index till where // the array elements are less than k int lessThanIndex = findLessThanK(arr, n, k); if (lessThanIndex == 0) return 0; return prefixFibSum[lessThanIndex - 1]; } // Driver Code int main() { int arr[] = { 1, 2, 3, 4, 2, 7 }; int n = sizeof (arr) / sizeof (arr[0]); // sort the array arr sort(arr, arr + n); // Build the prefix fibonacci sum array int * prefixFibSum = buildPrefixFibonacciSum(arr, n); // query array stores q queries int query[] = { 2, 6 }; int q = sizeof (query) / sizeof (query[0]); for ( int i = 0; i < q; i++) { int k = query[i]; int ans = processQuery(arr, prefixFibSum, n, k); cout << "Query " << i + 1 << " : " << ans << endl; } return 0; } |
Java
// Java program to find fibonacci sum of // subarray where all elements <= k import java.util.*; class GFG { // Helper function that multiplies 2 matrices // F and M of size 2*2, and puts the multiplication // result back to F[][] static void multiply( int [][] F, int [][] M) { int x = F[ 0 ][ 0 ] * M[ 0 ][ 0 ] + F[ 0 ][ 1 ] * M[ 1 ][ 0 ]; int y = F[ 0 ][ 0 ] * M[ 0 ][ 1 ] + F[ 0 ][ 1 ] * M[ 1 ][ 1 ]; int z = F[ 1 ][ 0 ] * M[ 0 ][ 0 ] + F[ 1 ][ 1 ] * M[ 1 ][ 0 ]; int w = F[ 1 ][ 0 ] * M[ 0 ][ 1 ] + F[ 1 ][ 1 ] * M[ 1 ][ 1 ]; F[ 0 ][ 0 ] = x; F[ 0 ][ 1 ] = y; F[ 1 ][ 0 ] = z; F[ 1 ][ 1 ] = w; } /* * Helper function that calculates F[][] raise to the power n and puts the * result in F[][] */ static void power( int [][] F, int n) { int i; int [][] M = { { 1 , 1 }, { 1 , 0 } }; // n - 1 times multiply the // matrix to {{1, 0}, {0, 1}} for (i = 2 ; i <= n; i++) multiply(F, M); } // Returns the nth fibonacci number static int fib( int n) { int [][] F = { { 1 , 1 }, { 1 , 0 } }; if (n == 0 ) return 0 ; power(F, n - 1 ); return F[ 0 ][ 0 ]; } static int findLessThanK( int arr[], int n, int k) { // find first index which is > k // using lower_bound return (lower_bound(arr, 0 , n, k + 1 )); } static int lower_bound( int [] a, int low, int high, int element) { while (low < high) { int middle = low + (high - low) / 2 ; if (element > a[middle]) low = middle + 1 ; else high = middle; } return low; } // Function to build Prefix Fibonacci Sum static int [] buildPrefixFibonacciSum( int arr[], int n) { // Allocate memory to prefix // fibonacci sum array int [] prefixFibSum = new int [n]; // Traverse the array from 0 to n - 1, // when at the ith index then we calculate // the a[i]th fibonacci number and calculate // the fibonacci sum till the ith index as // the sum of fibonacci sum till index i - 1 // and the a[i]th fibonacci number for ( int i = 0 ; i < n; i++) { int currFibNumber = fib(arr[i]); if (i == 0 ) { prefixFibSum[i] = currFibNumber; } else { prefixFibSum[i] = prefixFibSum[i - 1 ] + currFibNumber; } } return prefixFibSum; } // Return the answer for each query static int processQuery( int arr[], int prefixFibSum[], int n, int k) { // index stores the index till where // the array elements are less than k int lessThanIndex = findLessThanK(arr, n, k); if (lessThanIndex == 0 ) return 0 ; return prefixFibSum[lessThanIndex - 1 ]; } // Driver Code public static void main(String[] args) { int arr[] = { 1 , 2 , 3 , 4 , 2 , 7 }; int n = arr.length; // sort the array arr Arrays.sort(arr); // Build the prefix fibonacci sum array int [] prefixFibSum = buildPrefixFibonacciSum(arr, n); // query array stores q queries int query[] = { 2 , 6 }; int q = query.length; for ( int i = 0 ; i < q; i++) { int k = query[i]; int ans = processQuery(arr, prefixFibSum, n, k); System.out.print( "Query " + (i + 1 ) + " : " + ans + "\n" ); } } } // This code is contributed by Rajput-Ji |
C#
// C# program to find fibonacci sum of // subarray where all elements <= k using System; class GFG { // Helper function that multiplies 2 matrices // F and M of size 2*2, and puts the multiplication // result back to F[,] static void multiply( int [,] F, int [,] M) { int x = F[0, 0] * M[0, 0] + F[0, 1] * M[1, 0]; int y = F[0, 0] * M[0, 1] + F[0, 1] * M[1, 1]; int z = F[1, 0] * M[0, 0] + F[1, 1] * M[1, 0]; int w = F[1, 0] * M[0, 1] + F[1, 1] * M[1, 1]; F[0, 0] = x; F[0, 1] = y; F[1, 0] = z; F[1, 1] = w; } /* * Helper function that calculates F[,] raise to the power n and puts the * result in F[,] */ static void power( int [,] F, int n) { int i; int [,] M = { { 1, 1 }, { 1, 0 } }; // n - 1 times multiply the // matrix to {{1, 0}, {0, 1}} for (i = 2; i <= n; i++) multiply(F, M); } // Returns the nth fibonacci number static int fib( int n) { int [,] F = {{ 1, 1 }, { 1, 0 }}; if (n == 0) return 0; power(F, n - 1); return F[0, 0]; } static int findLessThanK( int []arr, int n, int k) { // find first index which is > k // using lower_bound return (lower_bound(arr, 0, n, k + 1)); } static int lower_bound( int [] a, int low, int high, int element) { while (low < high) { int middle = low + (high - low) / 2; if (element > a[middle]) low = middle + 1; else high = middle; } return low; } // Function to build Prefix Fibonacci Sum static int [] buildPrefixFibonacciSum( int []arr, int n) { // Allocate memory to prefix // fibonacci sum array int [] prefixFibSum = new int [n]; // Traverse the array from 0 to n - 1, // when at the ith index then we calculate // the a[i]th fibonacci number and calculate // the fibonacci sum till the ith index as // the sum of fibonacci sum till index i - 1 // and the a[i]th fibonacci number for ( int i = 0; i < n; i++) { int currFibNumber = fib(arr[i]); if (i == 0) { prefixFibSum[i] = currFibNumber; } else { prefixFibSum[i] = prefixFibSum[i - 1] + currFibNumber; } } return prefixFibSum; } // Return the answer for each query static int processQuery( int []arr, int []prefixFibSum, int n, int k) { // index stores the index till where // the array elements are less than k int lessThanIndex = findLessThanK(arr, n, k); if (lessThanIndex == 0) return 0; return prefixFibSum[lessThanIndex - 1]; } // Driver Code public static void Main(String[] args) { int []arr = { 1, 2, 3, 4, 2, 7 }; int n = arr.Length; // sort the array arr Array.Sort(arr); // Build the prefix fibonacci sum array int [] prefixFibSum = buildPrefixFibonacciSum(arr, n); // query array stores q queries int []query = {2, 6}; int q = query.Length; for ( int i = 0; i < q; i++) { int k = query[i]; int ans = processQuery(arr, prefixFibSum, n, k); Console.Write( "Query " + (i + 1) + " : " + ans + "\n" ); } } } // This code is contributed by PrinciRaj1992 |
Javascript
<script> // Javascript program to find fibonacci sum of // subarray where all elements <= k // Helper function that multiplies 2 matrices // F and M of size 2*2, and puts the multiplication // result back to F[,] function multiply(F, M) { let x = F[0][0] * M[0][0] + F[0][1] * M[1][0]; let y = F[0][0] * M[0][1] + F[0][1] * M[1][1]; let z = F[1][0] * M[0][0] + F[1][1] * M[1][0]; let w = F[1][0] * M[0][1] + F[1][1] * M[1][1]; F[0][0] = x; F[0][1] = y; F[1][0] = z; F[1][1] = w; } /* * Helper function that calculates F[,] raise to the power n and puts the * result in F[,] */ function power(F, n) { let i; let M = [[1, 1], [1, 0]]; // n - 1 times multiply the // matrix to {{1, 0}, {0, 1}} for (i = 2; i <= n; i++) multiply(F, M); } // Returns the nth fibonacci number function fib(n) { let F = [[1, 1], [1, 0]]; if (n == 0) return 0; power(F, n - 1); return F[0][0]; } function findLessThanK(arr, n, k) { // find first index which is > k // using lower_bound return (lower_bound(arr, 0, n, k + 1)); } function lower_bound(a, low, high, element) { while (low < high) { let middle = Math.floor(low + (high - low) / 2); if (element > a[middle]) low = middle + 1; else high = middle; } return low; } // Function to build Prefix Fibonacci Sum function buildPrefixFibonacciSum(arr, n) { // Allocate memory to prefix // fibonacci sum array let prefixFibSum = new Array(n); // Traverse the array from 0 to n - 1, // when at the ith index then we calculate // the a[i]th fibonacci number and calculate // the fibonacci sum till the ith index as // the sum of fibonacci sum till index i - 1 // and the a[i]th fibonacci number for (let i = 0; i < n; i++) { let currFibNumber = fib(arr[i]); if (i == 0) { prefixFibSum[i] = currFibNumber; } else { prefixFibSum[i] = prefixFibSum[i - 1] + currFibNumber; } } return prefixFibSum; } // Return the answer for each query function processQuery(arr, prefixFibSum, n, k) { // index stores the index till where // the array elements are less than k let lessThanIndex = findLessThanK(arr, n, k); if (lessThanIndex == 0) return 0; return prefixFibSum[lessThanIndex - 1]; } // Driver Code let arr = [1, 2, 3, 4, 2, 7]; let n = arr.length; // sort the array arr arr.sort((a, b) => a - b); // Build the prefix fibonacci sum array let prefixFibSum = buildPrefixFibonacciSum(arr, n); // query array stores q queries let query = [2, 6]; let q = query.length; for (let i = 0; i < q; i++) { let k = query[i]; let ans = processQuery(arr, prefixFibSum, n, k); document.write( "Query " + (i + 1) + " : " + ans + "<br>" ); } // This code is contributed by gfgking </script> |
Python3
# Python3 program to find fibonacci sum of # subarray where all elements <= k from bisect import bisect # Helper function that multiplies 2 matrices # F and M of size 2*2, and puts the multiplication # result back to F def multiply(F, M): x = F[ 0 ][ 0 ] * M[ 0 ][ 0 ] + F[ 0 ][ 1 ] * M[ 1 ][ 0 ] y = F[ 0 ][ 0 ] * M[ 0 ][ 1 ] + F[ 0 ][ 1 ] * M[ 1 ][ 1 ] z = F[ 1 ][ 0 ] * M[ 0 ][ 0 ] + F[ 1 ][ 1 ] * M[ 1 ][ 0 ] w = F[ 1 ][ 0 ] * M[ 0 ][ 1 ] + F[ 1 ][ 1 ] * M[ 1 ][ 1 ] F[ 0 ][ 0 ] = x F[ 0 ][ 1 ] = y F[ 1 ][ 0 ] = z F[ 1 ][ 1 ] = w # Helper function that calculates F # raise to the power n and puts the # result in F def power(F, n): M = [[ 1 , 1 ], [ 1 , 0 ]] # n - 1 times multiply the # matrix to [[1, 0], [0, 1]] for i in range ( 1 , n): multiply(F, M) # Returns the nth fibonacci number def fib(n): F = [[ 1 , 1 ], [ 1 , 0 ]] if (n = = 0 ): return 0 power(F, n - 1 ) return F[ 0 ][ 0 ] def findLessThanK(arr, n, k): # find first index which is > k # using bisect return (bisect(arr, k)) # Function to build Prefix Fibonacci Sum def buildPrefixFibonacciSum(arr, n): # Allocate memory to prefix # fibonacci sum array prefixFibSum = [ 0 ] * n # Traverse the array from 0 to n - 1, # when at the ith index then we calculate # the a[i]th fibonacci number and calculate # the fibonacci sum till the ith index as # the sum of fibonacci sum till index i - 1 # and the a[i]th fibonacci number for i in range (n): currFibNumber = fib(arr[i]) if (i = = 0 ): prefixFibSum[i] = currFibNumber else : prefixFibSum[i] = prefixFibSum[i - 1 ] + currFibNumber return prefixFibSum # Return the answer for each query def processQuery(arr, prefixFibSum, n, k): # index stores the index till where # the array elements are less than k lessThanIndex = findLessThanK(arr, n, k) if (lessThanIndex = = 0 ): return 0 return prefixFibSum[lessThanIndex - 1 ] # Driver Code if __name__ = = '__main__' : arr = [ 1 , 2 , 3 , 4 , 2 , 7 ] n = len (arr) # sort the array arr arr.sort() # Build the prefix fibonacci sum array prefixFibSum = buildPrefixFibonacciSum(arr, n) # query array stores q queries query = [ 2 , 6 ] q = len (query) for i in range (q): k = query[i] ans = processQuery(arr, prefixFibSum, n, k) print ( "Query {} : {}" . format (i + 1 , ans)) # This code is contributed by Amartya Ghosh |
Query 1 : 3 Query 2 : 8
Time Complexity : O(nlogn + qlogn)
Auxiliary Space: O(N)
Method 2 (Offline Querying) :
In offline querying, store the queries and calculate the answer for each query in a specific order and store and output the result of the queries in the original specified order.
Store each query as a pair of integers where the first member of the pair is the query parameter K for that query and the second member of the pair is the index at which the query occurs originally.
E.g. If queries are following :
query 1 : K = 13;
query 2 : K = 3;
query 3 : K = 8;
then, store query 1 as where 13 is the value of K for that query and 1 is the index specifying that it is the 1st query, similarly query 2 and query 3 are represented as and respectively.
Once, all individual queries are represented as pairs of integers sort the array of query pairs on the basis on K in increasing fashion.
E.g. the above queries after sorting will look like {3 ,8 ,13}.
Idea behind sorting queries :
The main idea behind sorting the queries is that when there are elements of a subset which are less than k for some query qi then for all queries qj where i < j and thus Ki <= Kj these elements are present so if the array of elements and the queries(sorted by K) both are sorted, then maintain two pointers one on the array and the other on the queries array.
i, pointing to ith index of the array,
j, pointing to jth index of the queries array
Then, consider the following Pseudo Code :
while (i <= query[j].K) { fibonacciSum = fibonacciSum + a[i]th Fibonacci number i = i + 1 }
So, while the elements in the subset are less than or equal to the current query pair’s first member (i.e K), keep on advancing to the next element while adding the required Fibonacci number to the current sum. Once the current element becomes greater than the parameter K of the current query store the current value of sum in the auxiliary array named ans of size q (i.e number of queries) at the index pointed by the 2nd member of the current query’s pair (i.e the original index at which the current query occurs).
ans[query[j].original index] = current value of fibonacciSum
At the end, print the ans array, which stores the result of all the queries in the order in which they were originally present.
Implementation:
CPP
// C++ program to find fibonacci sum of // subarray where all elements <= k #include <bits/stdc++.h> using namespace std; // structure where K is the query parameter // and original index is the index where the // query was originally present at. struct offlineQuery { int K, originalIndex; }; // function tp compare queries bool cmp(offlineQuery q1, offlineQuery q2) { return q1.K < q2.K; } /* Helper function that multiplies 2 matrices F and M of size 2*2, and puts the multiplication result back to F[][] */ void multiply( int F[2][2], int M[2][2]) { int x = F[0][0] * M[0][0] + F[0][1] * M[1][0]; int y = F[0][0] * M[0][1] + F[0][1] * M[1][1]; int z = F[1][0] * M[0][0] + F[1][1] * M[1][0]; int w = F[1][0] * M[0][1] + F[1][1] * M[1][1]; F[0][0] = x; F[0][1] = y; F[1][0] = z; F[1][1] = w; } /* Helper function that calculates F[][] raise to the power n and puts the result in F[][] */ void power( int F[2][2], int n) { int i; int M[2][2] = { { 1, 1 }, { 1, 0 } }; // n - 1 times multiply the // matrix to {{1, 0}, {0, 1}} for (i = 2; i <= n; i++) multiply(F, M); } // Returns the nth fibonacci number int fib( int n) { int F[2][2] = { { 1, 1 }, { 1, 0 } }; if (n == 0) return 0; power(F, n - 1); return F[0][0]; } // Return the answer for each query int * processQuery( int arr[], int queries[], int n, int q) { // build offline queries where each query // is of type offlineQuery which stores // both K and original Index of the query // in the queries array offlineQuery* offlineQueries = new offlineQuery[q]; // Allocate memory to store ans of each query int * ans = new int [q]; for ( int i = 0; i < q; i++) { int original_index = i; int K = queries[i]; offlineQueries[i].K = K; offlineQueries[i].originalIndex = original_index; } // sort offlineQueries[] sort(offlineQueries, offlineQueries + q, cmp); // i is pointing to the current position // array arr fibonacciSum store the // fibonacciSum till ith index int i = 0, fibonacciSum = 0; for ( int j = 0; j < q; j++) { int currK = offlineQueries[j].K; int currQueryIndex = offlineQueries[j].originalIndex; // keep inserting elements to subset // while elements are less than // current query's K value while (i < n && arr[i] <= currK) { fibonacciSum += fib(arr[i]); i++; } // store the current value of // fibonacci sum in the array ans // which stores results for the // queries in the original order ans[currQueryIndex] = fibonacciSum; } return ans; } // Driver Code int main() { int arr[] = { 1, 2, 3, 4, 2, 7 }; int n = sizeof (arr) / sizeof (arr[0]); // sort the array arr sort(arr, arr + n); // query array stores q queries int queries[] = { 2, 10, 6 }; int q = sizeof (queries) / sizeof (queries[0]); // res stores the result of each query int * res = processQuery(arr, queries, n, q); for ( int i = 0; i < q; i++) { int ans = res[i]; cout << "Query " << i + 1 << " : " << ans << endl; } return 0; } |
Java
//java program to find fibonacci sum of // subarray where all elements <= k import java.io.*; import java.util.*; // structure where K is the query parameter // and original index is the index where the // query was originally present at. class offlineQuery { int K = 0 ; int originalIndex = 0 ; } public class Main { /* Helper function that multiplies 2 matrices F and M of size 2*2, and puts the multiplication result back to F[][] */ public static void multiply( int [][] F, int [][] M) { int x = F[ 0 ][ 0 ] * M[ 0 ][ 0 ] + F[ 0 ][ 1 ] * M[ 1 ][ 0 ]; int y = F[ 0 ][ 0 ] * M[ 0 ][ 1 ] + F[ 0 ][ 1 ] * M[ 1 ][ 1 ]; int z = F[ 1 ][ 0 ] * M[ 0 ][ 0 ] + F[ 1 ][ 1 ] * M[ 1 ][ 0 ]; int w = F[ 1 ][ 0 ] * M[ 0 ][ 1 ] + F[ 1 ][ 1 ] * M[ 1 ][ 1 ]; F[ 0 ][ 0 ] = x; F[ 0 ][ 1 ] = y; F[ 1 ][ 0 ] = z; F[ 1 ][ 1 ] = w; } /* Helper function that calculates F[][] raise to the power n and puts the result in F[][] */ public static void power( int [][] F, int n) { int i = 0 ; int [][] M = { { 1 , 1 }, { 1 , 0 } }; // n - 1 times multiply the // matrix to {{1, 0}, {0, 1}} for (i = 2 ; i <= n; i++) multiply(F, M); } // Returns the nth fibonacci number public static int fib( int n) { int [][] F = { { 1 , 1 }, { 1 , 0 } }; if (n == 0 ) return 0 ; power(F, n - 1 ); return F[ 0 ][ 0 ]; } // Return the answer for each query public static int [] processQuery( int arr[], int queries[], int n, int q) { // build offline queries where each query // is of type offlineQuery which stores // both K and original Index of the query // in the queries array offlineQuery[] offlineQueries = new offlineQuery[q]; // Allocate memory to store ans of each query int [] ans = new int [q]; for ( int i = 0 ; i < q; i++) { int original_index = i; int K = queries[i]; offlineQueries[i] = new offlineQuery(); offlineQueries[i].K = K; offlineQueries[i].originalIndex = original_index; } // sort offlineQueries[] Arrays.sort(offlineQueries, new Comparator<offlineQuery>() { public int compare(offlineQuery idx1, offlineQuery idx2) { return idx1.K - idx2.K; } }); // i is pointing to the current position // array arr fibonacciSum store the // fibonacciSum till ith index int i = 0 ; int fibonacciSum = 0 ; for ( int j = 0 ; j < q; j++) { int currK = offlineQueries[j].K; int currQueryIndex = offlineQueries[j].originalIndex; // keep inserting elements to subset // while elements are less than // current query's K value while (i < n && arr[i] <= currK) { fibonacciSum += fib(arr[i]); i++; } // store the current value of // fibonacci sum in the array ans // which stores results for the // queries in the original order ans[currQueryIndex] = fibonacciSum; } return ans; } public static void main(String[] args) { int arr[] = { 1 , 2 , 3 , 4 , 2 , 7 }; int n = arr.length; // sort the array arr Arrays.sort(arr); // query array stores q queries int queries[] = { 2 , 10 , 6 }; int q = queries.length; // res stores the result of each query int [] res = processQuery(arr, queries, n, q); for ( int i = 0 ; i < q; i++) { int ans = res[i]; System.out.println( "Query " + i + 1 + " : " + ans); } } } // The code is contributed by Nidhi goel. |
Python3
# Python3 program to find fibonacci sum of # subarray where all elements <= k from bisect import bisect # Helper function that multiplies 2 matrices # F and M of size 2*2, and puts the multiplication # result back to F def multiply(F, M): x = F[ 0 ][ 0 ] * M[ 0 ][ 0 ] + F[ 0 ][ 1 ] * M[ 1 ][ 0 ] y = F[ 0 ][ 0 ] * M[ 0 ][ 1 ] + F[ 0 ][ 1 ] * M[ 1 ][ 1 ] z = F[ 1 ][ 0 ] * M[ 0 ][ 0 ] + F[ 1 ][ 1 ] * M[ 1 ][ 0 ] w = F[ 1 ][ 0 ] * M[ 0 ][ 1 ] + F[ 1 ][ 1 ] * M[ 1 ][ 1 ] F[ 0 ][ 0 ] = x F[ 0 ][ 1 ] = y F[ 1 ][ 0 ] = z F[ 1 ][ 1 ] = w # Helper function that calculates F # raise to the power n and puts the # result in F def power(F, n): M = [[ 1 , 1 ], [ 1 , 0 ]] # n - 1 times multiply the # matrix to [[1, 0], [0, 1]] for i in range ( 1 , n): multiply(F, M) # Returns the nth fibonacci number def fib(n): F = [[ 1 , 1 ], [ 1 , 0 ]] if (n = = 0 ): return 0 power(F, n - 1 ) return F[ 0 ][ 0 ] # Return the answer for each query def processQuery(arr, queries, n, q): # build offline queries where each query # is of type tuple which stores # both K and original Index of the query # in the queries array offlineQueries = [ None ] * q # Allocate memory to store ans of each query ans = [ 0 ] * q for i in range (q) : original_index = i K = queries[i] offlineQueries[i] = (K,original_index) # sort offlineQueries offlineQueries.sort() # i is pointing to the current position # array arr fibonacciSum store the # fibonacciSum till ith index i,fibonacciSum = 0 , 0 for j in range (q): currK = offlineQueries[j][ 0 ] currQueryIndex = offlineQueries[j][ 1 ] # keep inserting elements to subset # while elements are less than # current query's K value while (i < n and arr[i] < = currK): fibonacciSum + = fib(arr[i]) i + = 1 # store the current value of # fibonacci sum in the array ans # which stores results for the # queries in the original order ans[currQueryIndex] = fibonacciSum return ans # Driver Code if __name__ = = '__main__' : arr = [ 1 , 2 , 3 , 4 , 2 , 7 ] n = len (arr) # sort the array arr arr.sort() # query array stores q queries queries = [ 2 , 10 , 6 ] q = len (queries) # res stores the result of each query res = processQuery(arr, queries, n, q) for i in range (q): ans = res[i] print ( "Query {} : {}" . format (i + 1 , ans)) |
C#
using System; using System.Collections.Generic; using System.Collections; using System.Linq; // C# program to find fibonacci sum of // subarray where all elements <= k // structure where K is the query parameter // and original index is the index where the // query was originally present at. class offlineQuery { public int K; public int originalIndex; public offlineQuery( int k, int original_index){ K = k; originalIndex = original_index; } } class HelloWorld { public static int cmp(offlineQuery q1, offlineQuery q2) { return q1.K - q2.K; } /* Helper function that multiplies 2 matrices F and M of size 2*2, and puts the multiplication result back to F[][] */ public static void multiply( int [][] F, int [][] M) { int x = F[0][0] * M[0][0] + F[0][1] * M[1][0]; int y = F[0][0] * M[0][1] + F[0][1] * M[1][1]; int z = F[1][0] * M[0][0] + F[1][1] * M[1][0]; int w = F[1][0] * M[0][1] + F[1][1] * M[1][1]; F[0][0] = x; F[0][1] = y; F[1][0] = z; F[1][1] = w; } /* Helper function that calculates F[][] raise to the power n and puts the result in F[][] */ public static void power( int [][] F, int n) { int i; int [][] M = new int [][]{ new int [] {1, 1}, new int [] {1, 0} }; // n - 1 times multiply the // matrix to {{1, 0}, {0, 1}} for (i = 2; i <= n; i++) multiply(F, M); } // Returns the nth fibonacci number public static int fib( int n) { int [][] F = new int [][]{ new int [] {1, 1}, new int [] {1, 0} }; if (n == 0) return 0; power(F, n - 1); return F[0][0]; } // Return the answer for each query public static List< int > processQuery( int [] arr, int [] queries, int n, int q) { // build offline queries where each query // is of type offlineQuery which stores // both K and original Index of the query // in the queries array offlineQuery[] offlineQueries = new offlineQuery[q]; // Allocate memory to store ans of each query List< int > ans = new List< int > (); for ( int j = 0; j < q; j++){ ans.Add(0); } for ( int j = 0; j < q; j++) { int original_index = j; int K = queries[j]; offlineQueries[j] = new offlineQuery(K, original_index); } // sort offlineQueries[] Array.Sort(offlineQueries, cmp); // i is pointing to the current position // array arr fibonacciSum store the // fibonacciSum till ith index int i = 0; int fibonacciSum = 0; for ( int j = 0; j < q; j++) { int currK = offlineQueries[j].K; int currQueryIndex = offlineQueries[j].originalIndex; // keep inserting elements to subset // while elements are less than // current query's K value while (i < n && arr[i] <= currK) { fibonacciSum += fib(arr[i]); i++; } // store the current value of // fibonacci sum in the array ans // which stores results for the // queries in the original order ans[currQueryIndex] = fibonacciSum; } return ans; } static void Main() { int [] arr = { 1, 2, 3, 4, 2, 7 }; int n = arr.Length; // sort the array arr Array.Sort(arr); // query array stores q queries int [] queries = { 2, 10, 6 }; int q = queries.Length; // res stores the result of each query List< int > res = processQuery(arr, queries, n, q); for ( int i = 0; i < q; i++) { int ans = res[i]; Console.WriteLine( "Query " + (i + 1) + " : " + ans); } } } // The code is contributed by Nidhi goel. |
Javascript
// JavaScript program to find fibonacci sum of // subarray where all elements <= k // structure where K is the query parameter // and original index is the index where the // query was originally present at. class offlineQuery{ constructor(K, originalIndex){ this .K = K; this .originalIndex = originalIndex; } } // function tp compare queries function cmp(q1, q2) { return q1.K - q2.K; } /* Helper function that multiplies 2 matrices F and M of size 2*2, and puts the multiplication result back to F[][] */ function multiply(F, M) { x = F[0][0] * M[0][0] + F[0][1] * M[1][0]; y = F[0][0] * M[0][1] + F[0][1] * M[1][1]; z = F[1][0] * M[0][0] + F[1][1] * M[1][0]; w = F[1][0] * M[0][1] + F[1][1] * M[1][1]; F[0][0] = x; F[0][1] = y; F[1][0] = z; F[1][1] = w; } /* Helper function that calculates F[][] raise to the power n and puts the result in F[][] */ function power(F, n) { let i; let M = [[1, 1 ], [1, 0]]; // n - 1 times multiply the // matrix to {{1, 0}, {0, 1}} for (i = 2; i <= n; i++) multiply(F, M); } // Returns the nth fibonacci number function fib(n) { let F = [[1, 1],[1, 0]]; if (n == 0) return 0; power(F, n - 1); return F[0][0]; } // Return the answer for each query function processQuery(arr, queries, n, q) { // build offline queries where each query // is of type offlineQuery which stores // both K and original Index of the query // in the queries array let offlineQueries = new Array(); // Allocate memory to store ans of each query let ans = new Array(q).fill(0); for (let i = 0; i < q; i++) { let original_index = i; let K = queries[i]; offlineQueries.push( new offlineQuery(K, original_index)); } // sort offlineQueries[] offlineQueries.sort(cmp); // i is pointing to the current position // array arr fibonacciSum store the // fibonacciSum till ith index let i = 0; let fibonacciSum = 0; for (let j = 0; j < q; j++) { let currK = offlineQueries[j].K; let currQueryIndex = offlineQueries[j].originalIndex; // keep inserting elements to subset // while elements are less than // current query's K value while (i < n && arr[i] <= currK) { fibonacciSum += fib(arr[i]); i++; } // store the current value of // fibonacci sum in the array ans // which stores results for the // queries in the original order ans[currQueryIndex] = fibonacciSum; } return ans; } // Driver Code let arr = [1, 2, 3, 4, 2, 7 ]; let n = arr.length; // sort the array arr arr.sort( function (a, b){ return a - b}); // query array stores q queries let queries = [2, 10, 6]; let q = queries.length; // res stores the result of each query let res = processQuery(arr, queries, n, q); for (let i = 0; i < q; i++) { let ans = res[i]; console.log( "Query" , i+1, ":" , ans); } // The code is contributed by Gautam goel (gautamgoel962) |
Query 1 : 3 Query 2 : 21 Query 3 : 8
Time Complexity : O(nlogn + qlogq)
Auxiliary Space: O(q)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!