Educational Codeforces Round 72 (Rated for Div. 2) C. The Number Of Good Substrings(思维)

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
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;
}

你可能感兴趣的:(思维)