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

📅  最后修改于: 2021-09-17 16:11:56             🧑  作者: Mango

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

例子:

天真的方法:

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

下面是上述方法的实现。

C++
// C++ program to count number of
// substring under given condition
#include 
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
// 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
# 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#
// 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


Javascript


C++
// C++ program to count number of
// substring under given condition
#include 
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 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
// 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 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
# 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 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
// 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 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


Javascript


输出:
25

时间复杂度: O(N 2 )

有效的方法:

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

观察这个方程,我们可以创建另一个数组 B[i] = i – k * prefix_sum[i],对于 0 <= k < n。所以,现在的问题是计算 B 中每个 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
// 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 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
// 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 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

蟒蛇3

# 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 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
// 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 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

Javascript


输出:
25

时间复杂度: O(N\sqrt{N})

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程