Open In App

Number of substrings with length divisible by the number of 1’s in it

Given a binary string S consisting of only 0’s and 1’s. Count the number of substrings of this string such that the length of the substring is divisible by the number of 1’s in the substring.

Examples:



Input: S = “01010” 
Output: 10

Input: S = “1111100000” 
Output: 25 



Naive Approach: 

number of 1’s in the substring [l: r] = prefix_sum[r] – prefix_sum[l – 1]  

Below is the implementation of the above approach.

// C++ program to count number of
// substring under given condition
#include <bits/stdc++.h>
using namespace std;
 
// Function return count of
// such substring
int countOfSubstrings(string s)
{
    int n = s.length();
 
    int prefix_sum[n] = { 0 };
 
    // Mark 1 at those indices
    // where '1' appears
    for (int i = 0; i < n; i++) {
        if (s[i] == '1')
            prefix_sum[i] = 1;
    }
 
    // Take prefix sum
    for (int i = 1; i < n; i++)
        prefix_sum[i] += prefix_sum[i - 1];
 
    int answer = 0;
 
    // Iterate through all the
    // substrings
    for (int i = 0; i < n; i++) {
        for (int j = i; j < n; j++) {
            int countOfOnes = prefix_sum[j]
                - (i - 1 >= 0 ?
                   prefix_sum[i - 1] : 0);
            int length = j - i + 1;
 
            if (countOfOnes > 0 &&
                length % countOfOnes == 0)
                answer++;
        }
    }
    return answer;
}
 
// Driver Code
int main()
{
    string S = "1111100000";
 
    cout << countOfSubstrings(S);
 
    return 0;
}

                    
// Java program to count number of
// subString under given condition
 
import java.util.*;
 
class GFG{
 
// Function return count of
// such substring
static int countOfSubStrings(String s)
{
    int n = s.length();
 
    int []prefix_sum = new int[n];
 
    // Mark 1 at those indices
    // where '1' appears
    for (int i = 0; i < n; i++) {
        if (s.charAt(i) == '1')
            prefix_sum[i] = 1;
    }
     
    // Take prefix sum
    for (int i = 1; i < n; i++)
        prefix_sum[i] += prefix_sum[i - 1];
 
    int answer = 0;
     
    // Iterate through all the
    // subStrings
    for (int i = 0; i < n; i++) {
        for (int j = i; j < n; j++) {
            int countOfOnes = prefix_sum[j]
                - (i - 1 >= 0 ?
                prefix_sum[i - 1] : 0);
            int length = j - i + 1;
 
            if (countOfOnes > 0 &&
                length % countOfOnes == 0)
                answer++;
        }
    }
    return answer;
}
 
// Driver Code
public static void main(String[] args)
{
    String S = "1111100000";
 
    System.out.print(countOfSubStrings(S));
 
}
}
 
// This code contributed by sapnasingh4991

                    
# Python3 program to count number of
# substring under given condition
 
# Function return count of
# such substring
def countOfSubstrings(s):
    n = len(s)
    prefix_sum = [0 for i in range(n)]
 
    # Mark 1 at those indices
    # where '1' appears
    for i in range(n):
        if (s[i] == '1'):
            prefix_sum[i] = 1
 
    # Take prefix sum
    for i in range(1, n, 1):
        prefix_sum[i] += prefix_sum[i - 1]
 
    answer = 0
 
    # Iterate through all the
    # substrings
    for i in range(n):
        for j in range(i, n, 1):
            if (i - 1 >= 0):
                countOfOnes = prefix_sum[j]- prefix_sum[i - 1]
            else:
                countOfOnes = prefix_sum[j]
            length = j - i + 1
 
            if (countOfOnes > 0 and length % countOfOnes == 0):
                answer += 1
 
    return answer
 
# Driver Code
if __name__ == '__main__':
    S = "1111100000"
 
    print(countOfSubstrings(S))
 
# This code is contributed by Bhupendra_Singh

                    
// C# program to count number of
// subString under given condition
using System;
 
class GFG{
 
// Function return count of
// such substring
static int countOfSubStrings(String s)
{
    int n = s.Length;
    int []prefix_sum = new int[n];
 
    // Mark 1 at those indices
    // where '1' appears
    for(int i = 0; i < n; i++)
    {
        if (s[i] == '1')
            prefix_sum[i] = 1;
    }
     
    // Take prefix sum
    for(int i = 1; i < n; i++)
        prefix_sum[i] += prefix_sum[i - 1];
 
    int answer = 0;
     
    // Iterate through all the
    // subStrings
    for(int i = 0; i < n; i++)
    {
        for(int j = i; j < n; j++)
        {
            int countOfOnes = prefix_sum[j] -
                                  (i - 1 >= 0 ?
                              prefix_sum[i - 1] : 0);
            int length = j - i + 1;
     
            if (countOfOnes > 0 &&
                length % countOfOnes == 0)
            answer++;
        }
    }
    return answer;
}
 
// Driver Code
public static void Main(String[] args)
{
    String S = "1111100000";
    Console.Write(countOfSubStrings(S));
}
}
 
// This code is contributed by Rohit_ranjan

                    
<script>
 
// Javascript program to count number of
// subString under given condition
 
// Function return count of
// such substring
function countOfSubStrings(s)
{
    let n = s.length;
   
    let prefix_sum = Array.from({length: n}, (_, i) => 0);
   
    // Mark 1 at those indices
    // where '1' appears
    for (let i = 0; i < n; i++) {
        if (s[i] == '1')
            prefix_sum[i] = 1;
    }
       
    // Take prefix sum
    for (let i = 1; i < n; i++)
        prefix_sum[i] += prefix_sum[i - 1];
   
    let answer = 0;
       
    // Iterate through all the
    // subStrings
    for (let i = 0; i < n; i++) {
        for (let j = i; j < n; j++) {
            let countOfOnes = prefix_sum[j]
                - (i - 1 >= 0 ?
                prefix_sum[i - 1] : 0);
            let length = j - i + 1;
   
            if (countOfOnes > 0 &&
                length % countOfOnes == 0)
                answer++;
        }
    }
    return answer;
}
 
// Driver Code
     
    let S = "1111100000";
   
    document.write(countOfSubStrings(S));
                     
</script>

                    

Output: 
25

 

Time Complexity: O(N2)

Auxiliary Space: O(N)

Efficient Approach: 

 r – l + 1 = k * (prefix_sum[r] – prefix_sum[l-1]), where k is some integer 

r – k * prefix_sum[r] = l – 1 – k * prefix_sum[l-1] 

Observing this equation, we can create another array of the B[i] = i – k * prefix_sum[i], for 0 <= k < n. So, the problem now is to calculate the number of pairs of equal integers in B for each k. 

 prefix_sum[r] – prefix_sum[l-1] = (r – l + 1)/k <= n/x  

(-1) *n*x <= i – k – prefix_sum[i] <= n 

Below is the implementation of the above approach. 

// C++ program to count number of
// substring under given condition
#include <bits/stdc++.h>
using namespace std;
 
// Function return count of such
// substring
int countOfSubstrings(string s)
{
 
    int n = s.length();
 
    // Selection of adequate x value
    int x = sqrt(n);
 
    // Store where 1's are located
    vector<int> ones;
 
    for (int i = 0; i < n; i++) {
        if (s[i] == '1')
            ones.push_back(i);
    }
 
    // If there are no ones,
    // then answer is 0
    if (ones.size() == 0)
        return 0;
 
    // For ease of implementation
    ones.push_back(n);
 
    // Count storage
    vector<int> totCount(n * x + n);
 
    int sum = 0;
 
    // Iterate on all k values less
    // than fixed x
    for (int k = 0; k <= x; k++) {
        // Keeps a count of 1's occurred
        // during string traversal
        int now = 0;
        totCount[k * n]++;
 
        // Iterate on string and modify
        // the totCount
        for (int j = 1; j <= n; j++) {
            // If this character is 1
            if (s[j - 1] == '1')
                now++;
            int index = j - k * now;
 
            // Add to the final sum/count
            sum += totCount[index + k * n];
             
            // Increase totCount at exterior
            // position
            totCount[index + k * n]++;
        }
        now = 0;
        totCount[k * n]--;
 
        for (int j = 1; j <= n; j++) {
            if (s[j - 1] == '1')
                now++;
            int index = j - k * now;
 
            // Reduce totCount at index + k*n
            totCount[index + k * n]--;
        }
    }
 
    // Slightly modified prefix sum storage
    int prefix_sum[n];
    memset(prefix_sum, -1, sizeof(prefix_sum));
 
    // Number of 1's till i-1
    int cnt = 0;
 
    for (int i = 0; i < n; i++) {
        prefix_sum[i] = cnt;
        if (s[i] == '1')
            cnt++;
    }
 
    // Traversing over string considering
    // each position and finding bounds
    // and count using the inequalities
    for (int k = 0; k < n; k++)
    {
        for (int j = 1; j <= (n / x)
             && prefix_sum[k] + j <= cnt; j++)
        {
            // Calculating bounds for l and r
            int l = ones[prefix_sum[k] + j - 1]
                    - k + 1;
             
            int r = ones[prefix_sum[k] + j] - k;
             
            l = max(l, j * (x + 1));
 
            // If valid then add to answer
            if (l <= r) {
                sum += r / j - (l - 1) / j;
            }
        }
    }
 
    return sum;
}
int main()
{
    string S = "1111100000";
 
    cout << countOfSubstrings(S);
 
    return 0;
}

                    
// Java program to count number of
// subString under given condition
import java.util.*;
 
class GFG{
 
// Function return count of such
// substring
static int countOfSubStrings(String s)
{
    int n = s.length();
 
    // Selection of adequate x value
    int x = (int)Math.sqrt(n);
 
    // Store where 1's are located
    Vector<Integer> ones = new Vector<Integer>();
 
    for(int i = 0; i < n; i++)
    {
        if (s.charAt(i) == '1')
            ones.add(i);
    }
 
    // If there are no ones,
    // then answer is 0
    if (ones.size() == 0)
        return 0;
 
    // For ease of implementation
    ones.add(n);
 
    // Count storage
    int []totCount = new int[n * x + n];
 
    int sum = 0;
 
    // Iterate on all k values less
    // than fixed x
    for(int k = 0; k <= x; k++)
    {
         
        // Keeps a count of 1's occurred
        // during String traversal
        int now = 0;
        totCount[k * n]++;
 
        // Iterate on String and modify
        // the totCount
        for(int j = 1; j <= n; j++)
        {
             
            // If this character is 1
            if (s.charAt(j - 1) == '1')
                now++;
                 
            int index = j - k * now;
 
            // Add to the final sum/count
            sum += totCount[index + k * n];
             
            // Increase totCount at exterior
            // position
            totCount[index + k * n]++;
        }
        now = 0;
        totCount[k * n]--;
 
        for(int j = 1; j <= n; j++)
        {
            if (s.charAt(j - 1) == '1')
                now++;
                 
            int index = j - k * now;
 
            // Reduce totCount at index + k*n
            totCount[index + k * n]--;
        }
    }
 
    // Slightly modified prefix sum storage
    int []prefix_sum = new int[n];
    Arrays.fill(prefix_sum, -1);
 
    // Number of 1's till i-1
    int cnt = 0;
 
    for(int i = 0; i < n; i++)
    {
        prefix_sum[i] = cnt;
        if (s.charAt(i) == '1')
            cnt++;
    }
 
    // Traversing over String considering
    // each position and finding bounds
    // and count using the inequalities
    for(int k = 0; k < n; k++)
    {
        for(int j = 1; j <= (n / x) &&
            prefix_sum[k] + j <= cnt; j++)
        {
             
            // Calculating bounds for l and r
            int l = ones.get(prefix_sum[k] + j - 1)-
                                             k + 1;
             
            int r = ones.get(prefix_sum[k] + j) - k;
            l = Math.max(l, j * (x + 1));
 
            // If valid then add to answer
            if (l <= r)
            {
                sum += r / j - (l - 1) / j;
            }
        }
    }
    return sum;
}
 
// Driver code
public static void main(String[] args)
{
    String S = "1111100000";
 
    System.out.print(countOfSubStrings(S));
}
}
 
// This code is contributed by Amit Katiyar

                    
# Python3 program to count number of
# substring under given condition
import math
 
# Function return count of such
# substring
def countOfSubstrings(s):
 
    n = len(s)
 
    # Selection of adequate x value
    x = int(math.sqrt(n))
 
    # Store where 1's are located
    ones = []
 
    for i in range (n):
        if (s[i] == '1'):
            ones.append(i)
 
    # If there are no ones,
    # then answer is 0
    if (len(ones) == 0):
        return 0
 
    # For ease of implementation
    ones.append(n)
 
    # Count storage
    totCount = [0] * (n * x + n)
 
    sum = 0
 
    # Iterate on all k values less
    # than fixed x
    for k in range(x + 1):
         
        # Keeps a count of 1's occurred
        # during string traversal
        now = 0
        totCount[k * n] += 1
 
        # Iterate on string and modify
        # the totCount
        for j in range(1, n + 1):
             
            # If this character is 1
            if (s[j - 1] == '1'):
                now += 1
            index = j - k * now
 
            # Add to the final sum/count
            sum += totCount[index + k * n]
             
            # Increase totCount at exterior
            # position
            totCount[index + k * n] += 1
         
        now = 0
        totCount[k * n] -= 1
 
        for j in range(1, n + 1):
            if (s[j - 1] == '1'):
                now += 1
            index = j - k * now
 
            # Reduce totCount at index + k*n
            totCount[index + k * n] -= 1
 
    # Slightly modified prefix sum storage
    prefix_sum = [-1] * n
 
    # Number of 1's till i-1
    cnt = 0
 
    for i in range(n):
        prefix_sum[i] = cnt
        if (s[i] == '1'):
            cnt += 1
     
    # Traversing over string considering
    # each position and finding bounds
    # and count using the inequalities
    for k in range(n):
        j = 1
        while (j <= (n // x) and
               prefix_sum[k] + j <= cnt):
         
            # Calculating bounds for l and r
            l = (ones[prefix_sum[k] + j - 1] -
                                      k + 1)
             
            r = ones[prefix_sum[k] + j] - k
            l = max(l, j * (x + 1))
 
            # If valid then add to answer
            if (l <= r):
                sum += r // j - (l - 1) // j
             
            j += 1
 
    return sum
 
# Driver code
if __name__ == "__main__":
     
    S = "1111100000"
 
    print (countOfSubstrings(S))
 
# This code is contributed by chitranayal

                    
// C# program to count number of
// subString under given condition
using System;
using System.Collections.Generic;
  
class GFG{
  
// Function return count of such
// substring
static int countOfSubStrings(String s)
{
    int n = s.Length;
  
    // Selection of adequate x value
    int x = (int)Math.Sqrt(n);
  
    // Store where 1's are located
    List<int> ones = new List<int>();
  
    for(int i = 0; i < n; i++)
    {
        if (s[i] == '1')
            ones.Add(i);
    }
  
    // If there are no ones,
    // then answer is 0
    if (ones.Count == 0)
        return 0;
  
    // For ease of implementation
    ones.Add(n);
  
    // Count storage
    int []totCount = new int[n * x + n];
  
    int sum = 0;
  
    // Iterate on all k values less
    // than fixed x
    for(int k = 0; k <= x; k++)
    {
          
        // Keeps a count of 1's occurred
        // during String traversal
        int now = 0;
        totCount[k * n]++;
  
        // Iterate on String and modify
        // the totCount
        for(int j = 1; j <= n; j++)
        {
              
            // If this character is 1
            if (s[j-1] == '1')
                now++;
                  
            int index = j - k * now;
  
            // Add to the readonly sum/count
            sum += totCount[index + k * n];
              
            // Increase totCount at exterior
            // position
            totCount[index + k * n]++;
        }
        now = 0;
        totCount[k * n]--;
  
        for(int j = 1; j <= n; j++)
        {
            if (s[j-1] == '1')
                now++;
                  
            int index = j - k * now;
  
            // Reduce totCount at index + k*n
            totCount[index + k * n]--;
        }
    }
  
    // Slightly modified prefix sum storage
    int []prefix_sum = new int[n];
    for(int i = 0; i < n; i++)
        prefix_sum [i]= -1;
  
    // Number of 1's till i-1
    int cnt = 0;
  
    for(int i = 0; i < n; i++)
    {
        prefix_sum[i] = cnt;
        if (s[i] == '1')
            cnt++;
    }
  
    // Traversing over String considering
    // each position and finding bounds
    // and count using the inequalities
    for(int k = 0; k < n; k++)
    {
        for(int j = 1; j <= (n / x) &&
            prefix_sum[k] + j <= cnt; j++)
        {
              
            // Calculating bounds for l and r
            int l = ones[prefix_sum[k] + j - 1]-
                                         k + 1;
              
            int r = ones[prefix_sum[k] + j] - k;
            l = Math.Max(l, j * (x + 1));
  
            // If valid then add to answer
            if (l <= r)
            {
                sum += r / j - (l - 1) / j;
            }
        }
    }
    return sum;
}
  
// Driver code
public static void Main(String[] args)
{
    String S = "1111100000";
  
    Console.Write(countOfSubStrings(S));
}
}
  
// This code is contributed by Amit Katiyar

                    
<script>
 
// Javascript program to count number of
// substring under given condition
 
// Function return count of such
// substring
function countOfSubstrings(s)
{
 
    var n = s.length;
 
    // Selection of adequate x value
    var x = parseInt(Math.sqrt(n));
 
    // Store where 1's are located
    var ones = [];
 
    for (var i = 0; i < n; i++) {
        if (s[i] == '1')
            ones.push(i);
    }
 
    // If there are no ones,
    // then answer is 0
    if (ones.length == 0)
        return 0;
 
    // For ease of implementation
    ones.push(n);
 
    // Count storage
    var totCount = Array(n * x + n).fill(0);
 
    var sum = 0;
 
    // Iterate on all k values less
    // than fixed x
    for (var k = 0; k <= x; k++) {
        // Keeps a count of 1's occurred
        // during string traversal
        var now = 0;
        totCount[k * n]++;
 
        // Iterate on string and modify
        // the totCount
        for (var j = 1; j <= n; j++) {
            // If this character is 1
            if (s[j - 1] == '1')
                now++;
            var index = j - k * now;
 
            // Add to the final sum/count
            sum += totCount[index + k * n];
             
            // Increase totCount at exterior
            // position
            totCount[index + k * n]++;
        }
        now = 0;
        totCount[k * n]--;
 
        for (var j = 1; j <= n; j++) {
            if (s[j - 1] == '1')
                now++;
            var index = j - k * now;
 
            // Reduce totCount at index + k*n
            totCount[index + k * n]--;
        }
    }
 
    // Slightly modified prefix sum storage
    var prefix_sum = Array(n).fill(-1);
 
    // Number of 1's till i-1
    var cnt = 0;
 
    for (var i = 0; i < n; i++) {
        prefix_sum[i] = cnt;
        if (s[i] == '1')
            cnt++;
    }
 
    // Traversing over string considering
    // each position and finding bounds
    // and count using the inequalities
    for (var k = 0; k < n; k++)
    {
        for (var j = 1; j <= parseInt(n / x)
             && prefix_sum[k] + j <= cnt; j++)
        {
            // Calculating bounds for l and r
            var l = ones[prefix_sum[k] + j - 1]
                    - k + 1;
             
            var r = ones[prefix_sum[k] + j] - k;
             
            l = Math.max(l, j * (x + 1));
 
            // If valid then add to answer
            if (l <= r) {
                sum += parseInt(r / j) - parseInt((l - 1) / j);
            }
        }
    }
 
    return sum;
}
 
 
var S = "1111100000";
document.write( countOfSubstrings(S));
 
 
</script>

                    

Output: 
25

Time Complexity :  

Auxiliary Space: O(N3/2)


 


Article Tags :