# 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 length of substring is divisible by the number of 1’s in the substring.

Examples:

Input: S = “01010”
Output: 10

Input: S = “1111100000”
Output: 25

## Recommended: Please try your approach on {IDE} first, before moving on to the solution.

Naive Approach:

• Iterate through all the substring and for each substring count the number of 1’s. If length of substring if divisible by count of 1’s then increase the count. This approach will take O(N3) time.
• To make the solution more efficient, instead of traversing the entire substring to count the number of 1’s in it, we can use Prefix Sum Array.

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++

 // C++ program to count number of   // substring under given condition   #include  using namespace std;     // Function return count of   // such substing  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

 // Java program to count number of   // subString under given condition      import java.util.*;     class GFG{     // Function return count of   // such substing  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

 # Python3 program to count number of   # substring under given condition      # Function return count of   # such substing  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#

 // C# program to count number of   // subString under given condition   using System;      class GFG{      // Function return count of   // such substing   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

Output:

25


Time Complexity: O(N2)

Efficient Approach:

• Let’s use the prefix sum array as discussed in the previous approach. Let’s take a substring [l: r] which follows the condition given, we can say that:

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

This can also be written as:

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.

• Let’s take a fixed number x. If k > x, then as r – l + 1 <= n ( for any pair of l, r ), we get the following inequality :

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

This goes on to show that number of ones and k are not large in substrings satisfying the given conditions. (this is just for estimation of efficiency).
Now for k <= x, we need to calculate the number of pairs of equal integers. The following inequality is satisfied here:

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

So, we can put all numbers into one array for each k independently and find the number of equal integers.

• The next step would be to fix values of l and iterate on the number of 1’s in the string, and for each value get the bounds for r. For a given count of the number of 1’s, we can evaluate which remainder will give r. The problem now becomes to calculate the number of integers on some segment, which give some fixed remainder (rem), when divided by some fixed integer. This calculation can be done in O(1). Also, note that it’s important to count only such r values for which k > x.

Below is the implementation of the above approach.

 // C++ program to count number of   // substring under given condition   #include  using namespace std;     // Function return count of such   // substing  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 occured          // 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;  }

Output:

25


Time Complexity : Don’t stop now and take your learning to the next level. Learn all the important concepts of Data Structures and Algorithms with the help of the most trusted course: DSA Self Paced. Become industry ready at a student-friendly price.

My Personal Notes arrow_drop_up Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.