<p>You are given a binary string <code>s</code>.</p>

<p>Return the number of <span data-keyword="substring-nonempty">substrings</span> with <strong>dominant</strong> ones.</p>

<p>A string has <strong>dominant</strong> ones if the number of ones in the string is <strong>greater than or equal to</strong> the <strong>square</strong> of the number of zeros in the string.</p>

<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>

<div class="example-block">
<p><strong>Input:</strong> <span class="example-io">s = &quot;00011&quot;</span></p>

<p><strong>Output:</strong> <span class="example-io">5</span></p>

<p><strong>Explanation:</strong></p>

<p>The substrings with dominant ones are shown in the table below.</p>
</div>

<table>
	<thead>
		<tr>
			<th>i</th>
			<th>j</th>
			<th>s[i..j]</th>
			<th>Number of Zeros</th>
			<th>Number of Ones</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>3</td>
			<td>3</td>
			<td>1</td>
			<td>0</td>
			<td>1</td>
		</tr>
		<tr>
			<td>4</td>
			<td>4</td>
			<td>1</td>
			<td>0</td>
			<td>1</td>
		</tr>
		<tr>
			<td>2</td>
			<td>3</td>
			<td>01</td>
			<td>1</td>
			<td>1</td>
		</tr>
		<tr>
			<td>3</td>
			<td>4</td>
			<td>11</td>
			<td>0</td>
			<td>2</td>
		</tr>
		<tr>
			<td>2</td>
			<td>4</td>
			<td>011</td>
			<td>1</td>
			<td>2</td>
		</tr>
	</tbody>
</table>

<p><strong class="example">Example 2:</strong></p>

<div class="example-block">
<p><strong>Input:</strong> <span class="example-io">s = &quot;101101&quot;</span></p>

<p><strong>Output:</strong> <span class="example-io">16</span></p>

<p><strong>Explanation:</strong></p>

<p>The substrings with <strong>non-dominant</strong> ones are shown in the table below.</p>

<p>Since there are 21 substrings total and 5 of them have non-dominant ones, it follows that there are 16 substrings with dominant ones.</p>
</div>

<table>
	<thead>
		<tr>
			<th>i</th>
			<th>j</th>
			<th>s[i..j]</th>
			<th>Number of Zeros</th>
			<th>Number of Ones</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>1</td>
			<td>1</td>
			<td>0</td>
			<td>1</td>
			<td>0</td>
		</tr>
		<tr>
			<td>4</td>
			<td>4</td>
			<td>0</td>
			<td>1</td>
			<td>0</td>
		</tr>
		<tr>
			<td>1</td>
			<td>4</td>
			<td>0110</td>
			<td>2</td>
			<td>2</td>
		</tr>
		<tr>
			<td>0</td>
			<td>4</td>
			<td>10110</td>
			<td>2</td>
			<td>3</td>
		</tr>
		<tr>
			<td>1</td>
			<td>5</td>
			<td>01101</td>
			<td>2</td>
			<td>3</td>
		</tr>
	</tbody>
</table>

<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>

<ul>
	<li><code>1 &lt;= s.length &lt;= 4 * 10<sup>4</sup></code></li>
	<li><code>s</code> consists only of characters <code>&#39;0&#39;</code> and <code>&#39;1&#39;</code>.</li>
</ul>

class Solution:
    def numberOfSubstrings(self, s: str) -> int:
        from math import sqrt
        from bisect import bisect_right
        
        answer = 0
        nums = [0] * len(s)
        zeros = [0] if s[0] == '0' else []
        
        nums[0] = [0, 1] if s[0] == '1' else [1, 0]
        
        for i in range(1, len(s)):
            if s[i] == '1':
                nums[i] = [nums[i - 1][0], nums[i - 1][1] + 1]
            else:
                nums[i] = [nums[i - 1][0] + 1, nums[i - 1][1]]
                zeros.append(i)
        
        for i in range(len(s)):         
            j = i
            minus = [0, 0]
            if i > 0:
                minus = nums[i - 1]
            while j < len(s):
                sqrted = int(sqrt((nums[j][1] - minus[1])))
                if (nums[j][0] - minus[0]) ** 2 > (nums[j][1] - minus[1]):
                    j += (nums[j][0] - minus[0]) ** 2 - (nums[j][1] - minus[1])
                
                elif sqrted >= (nums[j][0] - minus[0]):
                    if sqrted >= nums[-1][0]:
                        skip = len(s) - j
                    else:
                        skip = min(sqrted - (nums[j][0] - minus[0]) + 1, len(s) - j)
                    z = bisect_right(zeros, j)
                    if z == len(zeros):
                        skip = len(s) - j
                    else:
                        skip = min(len(s) - j, zeros[z] - j)
                    answer += skip
                    j += skip
                else:
                    if (nums[j][1] - minus[1]) >= (nums[j][0] - minus[0]) ** 2:
                        answer += 1
                    j+= 1
                
        return answer
22900