Open In App

Fibonacci sum of a subset with all elements <= k

Last Updated : 06 Mar, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

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 :

  1. Online Querying, 
  2. 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


Output

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)


Output

Query  1 : 3
Query  2 : 21
Query  3 : 8

Time Complexity : O(nlogn + qlogq)
 Auxiliary Space: O(q)



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads