📌  相关文章
📜  子串的数目,其长度可被其中的1的数目整除

📅  最后修改于: 2021-04-22 00:17:09             🧑  作者: Mango

给定一个仅由0和1组成的二进制字符串S。计算此字符串的子字符串数,以使子字符串的长度可被子字符串中的1数除尽。
例子:

天真的方法:

  • 遍历所有子字符串,并为每个子字符串计数1的数目。如果子串的长度可以被计数1整除,则增加计数。这种方法将花费O(N 3 )时间。
  • 为了使解决方案更有效,我们可以使用前缀求和数组,而不是遍历整个子字符串以计算其中的1的数目。

下面是上述方法的实现。

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


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();
  
    // Selection of adequate x value
    int x = sqrt(n);
  
    // Store where 1's are located
    vector 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 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;
}


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();
  
    // Selection of adequate x value
    int x = (int)Math.sqrt(n);
  
    // Store where 1's are located
    Vector ones = new Vector();
  
    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 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.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
# Python3 program to count number of 
# substring under given condition 
import math
  
# Function return count of such 
# substing
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 occured
        # 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#
// C# program to count number of 
// subString under given condition 
using System;
using System.Collections.Generic;
   
class GFG{
   
// Function return count of such 
// substing
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 ones = new List();
   
    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 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 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


输出:
25



时间复杂度: O(N 2 )
高效方法:

  • 让我们使用前面方法中讨论的前缀和数组。我们来看一个遵循给定条件的子字符串[l:r],可以这样说:

    也可以写成:

    观察这个方程,我们可以创建另一个B [i] = i – k * prefix_sum [i]的数组,其中0 <= k

  • 让我们取一个固定的数x。如果k> x,则当r – l + 1 <= n(对于任何l,r对)时,我们得到以下不等式:

    这继续表明,在满足给定条件的子字符串中,1和k的数量并不大。 (这只是为了估计效率)。现在,对于k <= x,我们需要计算相等整数对的数量。此处满足以下不等式:

    因此,我们可以将所有数字分别独立地放入每个k的一个数组中,并找到相等整数的数量。

  • 下一步将固定l的值,并在字符串的1的数目上进行迭代,并对每个值获取r的范围。对于给定的1的数量,我们可以评估哪个余数将给出r。现在的问题是要计算某个段上的整数数量,当将其除以某个固定整数时,该整数给出一些固定的余数(rem)。该计算可以在O(1)中完成。另外,请注意仅计算k> x的r值很重要。

下面是上述方法的实现。

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();
  
    // Selection of adequate x value
    int x = sqrt(n);
  
    // Store where 1's are located
    vector 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 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;
}

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();
  
    // Selection of adequate x value
    int x = (int)Math.sqrt(n);
  
    // Store where 1's are located
    Vector ones = new Vector();
  
    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 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.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

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

// C# program to count number of 
// subString under given condition 
using System;
using System.Collections.Generic;
   
class GFG{
   
// Function return count of such 
// substing
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 ones = new List();
   
    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 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 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
输出:
25

时间复杂度:

O(N\sqrt{N})