Open In App

Count subarrays such that remainder after dividing sum of elements by K gives count of elements

Last Updated : 03 Jun, 2021
Comments
Improve
Suggest changes
Like Article
Like
Report

Given an array arr[] of size N and an element K. The task is to find the number of sub-arrays of the given array such that the remainder when dividing the sum of its elements by K is equal to the number of elements in the subarray.

Examples: 

Input: arr[] = {1, 4, 2, 3, 5}, K = 4 
Output:
{1}, {1, 4, 2}, {4, 2} and {5} 
are the only valid subarrays.
Input: arr[] = {4, 2, 4, 2, 4, 2, 4, 2}, K = 4 
Output:

Approach: Let’s define a sequence Sn such that Si = A1 + A2 + ··· + Ai and S0 = 0. Then, the condition that a contiguous subsequence Ai+1, ..., Aj is valid can be represented as (Sj - Si) % K = j - i
This equation can then be transformed into the following equivalent conditions: 
(Sj - j) % K = (Si - i) % K and j - i < K
Therefore, for each j(1 ? j ? N), count the number of j - K < i < j such that (Sj - j) % K = (Si - i) % K. For j the segment needed to be searched is (j - K, j), and for j + 1, it is (j - K + 1, j + 1), and these differ only by one element at the leftmost and rightmost, so in order to search for (j + 1)th after searching for jth element, only discard the leftmost element and add the rightmost element. Operations of discarding or adding can be performed quickly by managing the number of Si - i's by using associative arrays (such as map in C++ or dict in Python).

Below is the implementation of the above approach: 

C++
// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;

// Function to return the number of subarrays
// of the given array such that the remainder
// when dividing the sum of its elements
// by K is equal to the number of its elements
int sub_arrays(int a[], int n, int k)
{

    // To store prefix sum
    int sum[n + 2] = { 0 };

    for (int i = 0; i < n; i++) {

        // We are dealing with zero
        // indexed array
        a[i]--;

        // Taking modulus value
        a[i] %= k;

        // Prefix sum
        sum[i + 1] += sum[i] + a[i];
        sum[i + 1] %= k;
    }

    // To store the required answer, the left
    // index and the right index
    int ans = 0, l = 0, r = 0;

    // To store si - i value
    map<int, int> mp;

    for (int i = 0; i < n + 1; i++) {

        // Include sum
        ans += mp[sum[i]];
        mp[sum[i]]++;

        // Increment the right index
        r++;

        // If subarray has at least
        // k elements
        if (r - l >= k) {
            mp[sum[l]]--;
            l++;
        }
    }

    // Return the required answer
    return ans;
}

// Driver code
int main()
{
    int a[] = { 1, 4, 2, 3, 5 };
    int n = sizeof(a) / sizeof(a[0]);

    int k = 4;

    // Function call
    cout << sub_arrays(a, n, k);

    return 0;
}
Java
// Java implementation of the approach 
import java.util.*; 

class gfg
{
    
    // Function to return the number of subarrays 
    // of the given array such that the remainder 
    // when dividing the sum of its elements 
    // by K is equal to the number of its elements 
    static int sub_arrays(int []a, int n, int k) 
    { 
    
        // To store prefix sum 
        int sum[] = new int[n + 2] ; 
        
        for (int i = 0; i < n+2; i++)
        { 
            sum[i] = 0;
        }
        
        for (int i = 0; i < n; i++) 
        { 
    
            // We are dealing with zero 
            // indexed array 
            a[i]--; 
    
            // Taking modulus value 
            a[i] %= k; 
    
            // Prefix sum 
            sum[i + 1] += sum[i] + a[i]; 
            sum[i + 1] %= k; 
        } 
    
        // To store the required answer, the left 
        // index and the right index 
        int ans = 0, l = 0, r = 0; 
    
        // To store si - i value 
        HashMap<Integer, Integer> mp = new HashMap<Integer, Integer>(); 
    
        for (int i = 0; i < n + 1; i++)
        { 
            mp.put(sum[i], 0);
        }
        int temp;
        
        for (int i = 0; i < n + 1; i++) 
        { 
    
            // Include sum 
            ans += (int)mp.get(sum[i]); 
            temp =(int)mp.get(sum[i]) + 1;
            mp.put(sum[i], temp); 
    
            // Increment the right index 
            r++; 
    
            // If subarray has at least 
            // k elements 
            if (r - l >= k)
            { 
                //mp[sum[l]]--; 
                temp = (int)mp.get(sum[l]) - 1;
                mp.put(sum[l], temp);
                l++; 
            } 
        } 
    
        // Return the required answer 
        return ans; 
    } 
    
    // Driver code 
    public static void main(String args[]) 
    { 
        int []a = { 1, 4, 2, 3, 5 }; 
        
        int n = a.length; 
    
        int k = 4; 
    
        // Function call 
        System.out.print(sub_arrays(a, n, k)); 
    
    } 
}

// This code is contributed by AnkitRai01
Python3
# Python3 implementation of the approach

# Function to return the number of 
# subarrays of the given array 
# such that the remainder when dividing 
# the sum of its elements by K is 
# equal to the number of its elements
def sub_arrays(a, n, k):

    # To store prefix sum
    sum = [0 for i in range(n + 2)]

    for i in range(n):

        # We are dealing with zero
        # indexed array
        a[i] -= 1

        # Taking modulus value
        a[i] %= k

        # Prefix sum
        sum[i + 1] += sum[i] + a[i]
        sum[i + 1] %= k

    # To store the required answer, 
    # the left index and the right index
    ans = 0
    l = 0
    r = 0

    # To store si - i value
    mp = dict()

    for i in range(n + 1):

        # Include sum
        if sum[i] in mp:
            ans += mp[sum[i]]
        mp[sum[i]] = mp.get(sum[i], 0) + 1

        # Increment the right index
        r += 1

        # If subarray has at least
        # k elements
        if (r - l >= k):
            mp[sum[l]] -= 1
            l += 1

    # Return the required answer
    return ans

# Driver code
a = [1, 4, 2, 3, 5]
n = len(a)

k = 4

# Function call
print(sub_arrays(a, n, k))

# This code is contributed by Mohit Kumar
C#
// C# implementation of the approach 
using System;
using System.Collections.Generic;

class gfg
{
    // Function to return the number of subarrays 
    // of the given array such that the remainder 
    // when dividing the sum of its elements 
    // by K is equal to the number of its elements 
    static int sub_arrays(int []a, int n, int k) 
    { 
    
        // To store prefix sum 
        int []sum = new int[n + 2] ; 
        
        for (int i = 0; i < n + 2; i++)
        { 
            sum[i] = 0;
        }
        
        for (int i = 0; i < n; i++) 
        { 
    
            // We are dealing with zero 
            // indexed array 
            a[i]--; 
    
            // Taking modulus value 
            a[i] %= k; 
    
            // Prefix sum 
            sum[i + 1] += sum[i] + a[i]; 
            sum[i + 1] %= k; 
        } 
    
        // To store the required answer, the left 
        // index and the right index 
        int ans = 0, l = 0, r = 0; 
    
        // To store si - i value 
        Dictionary<int, int> mp = new Dictionary<int, int>(); 
    
        for (int i = 0; i < n + 1; i++)
        { 
            if(!mp.ContainsKey(sum[i]))
                mp.Add(sum[i], 0);
        }
        int temp;
        
        for (int i = 0; i < n + 1; i++) 
        { 
    
            // Include sum 
            ans += (int)mp[sum[i]]; 
            temp =(int)mp[sum[i]] + 1;
            mp[sum[i]] = temp; 
    
            // Increment the right index 
            r++; 
    
            // If subarray has at least 
            // k elements 
            if (r - l >= k)
            { 
                //mp[sum[l]]--; 
                temp = (int)mp[sum[l]] - 1;
                mp[sum[i]] = temp; 
                l++; 
            } 
        } 
    
        // Return the required answer 
        return ans; 
    } 
    
    // Driver code 
    public static void Main(String []args) 
    { 
        int []a = { 1, 4, 2, 3, 5 }; 
        
        int n = a.Length; 
    
        int k = 4; 
    
        // Function call 
        Console.Write(sub_arrays(a, n, k)); 
    } 
}

// This code is contributed by 29AjayKumar
JavaScript
<script>

// JavaScript implementation of the approach

// Function to return the number of subarrays
// of the given array such that the remainder
// when dividing the sum of its elements
// by K is equal to the number of its elements
function sub_arrays(a, n, k) {

    // To store prefix sum
    let sum = new Array(n + 2);

    for (let i = 0; i < n + 2; i++) {
        sum[i] = 0;
    }

    for (let i = 0; i < n; i++) {

        // We are dealing with zero
        // indexed array
        a[i]--;

        // Taking modulus value
        a[i] %= k;

        // Prefix sum
        sum[i + 1] += sum[i] + a[i];
        sum[i + 1] %= k;
    }

    // To store the required answer, the left
    // index and the right index
    let ans = 0, l = 0, r = 0;

    // To store si - i value
    let mp = new Map();

    for (let i = 0; i < n + 1; i++) {
        if (!mp.has(sum[i]))
            mp.set(sum[i], 0);
    }
    let temp;

    for (let i = 0; i < n + 1; i++) {

        // Include sum
        ans += mp.get(sum[i]);
        temp = mp.get(sum[i]) + 1;
        mp.set(sum[i], temp);

        // Increment the right index
        r++;

        // If subarray has at least
        // k elements
        if (r - l >= k) {
            //mp[sum[l]]--;
            temp = mp.get(sum[l]) - 1;
            mp.set(sum[i], temp);
            l++;
        }
    }

    // Return the required answer
    return ans;
}

// Driver code

let a = [1, 4, 2, 3, 5];

let n = a.length;

let k = 4;

// Function call
document.write(sub_arrays(a, n, k));

// This code is contributed by _saurabh_jaiswal

</script>

Output:

4

Time Complexity: O(N* log(N))
Auxiliary Space: O(N)


Article Tags :
Practice Tags :

Explore