You are given a binary string s (recall that a string is binary if each character is either 0 or 1).
Let f(t) be the decimal representation of integer t written in binary form (possibly with leading zeroes). For example f(011)=3,f(00101)=5,f(00001)=1,f(10)=2,f(000)=0 and f(000100)=4.
The substring sl,sl+1,…,sr is good if r−l+1=f(sl…sr).
For example string s=1011 has 5 good substrings: s1…s1=1, s3…s3=1, s4…s4=1, s1…s2=10 and s2…s4=011.
Your task is to calculate the number of good substrings of string s.
You have to answer t independent queries.
Input
The first line contains one integer t (1≤t≤1000) — the number of queries.
The only line of each query contains string s (1≤|s|≤2⋅105), consisting of only digits 0 and 1.
It is guaranteed that ∑i=1t|si|≤2⋅105.
Output
For each query print one integer — the number of good substrings of string s.
Example
inputCopy
4
0110
0101
00001000
0001000
outputCopy
4
3
4
3
题意: 有一个由0和1组成的字符串,如果在区间[l,r]中转换的十进制数num = r-l+1,即十进制数num = 长度len,则是good。问有多少个good。
思路: 通过观察,我们可以得知,当区间长度为2e5时,即[1,2e5]转换的十进制为2e5,则2e5转换的二进制最多为11个数,其他数全为前导0。所以,我们只需要记录前导0的个数,当s[i] != ‘0’时,记录当前数,若num <= len + r -l +1 则存在一个good,反之直接跳出即可。
代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int T;
scanf("%d",&T);
while(T--){
string s; cin>>s;
int num_0 = 0,sum = 0;
for(int i = 0; s[i]; ++i){
if(s[i] == '0'){ num_0++; continue; }
int num = 0;
for(int j = i; s[j]; ++j){
num = (num<<1) + s[j] - '0';
if(num <= j - i + 1 + num_0) sum++;
else break;
}
num_0 = 0;
}
printf("%d\n",sum);
}
return 0;
}