总结:
C. The Number Of Good Substrings
思路:题目是找字符串中s[l…r]的二进制值等于 r-l+1,找出多少种可能。
比赛的时候我是直接用个数组存l到r的二进制值,最后超出内存了,最近都没注意这个,上次做dp也是,一维能解决的非得用二维,改。
实际上直接遍历字符串找1位置进行计算就可以了。
找到1的时候就说明l到r这段子串的值非0,才可以进行计算。
遍历字符串暴力计算就可以了,每次计算x是否小于pos-i+1,如果是ans++,不是就跳出循环即可。
#include<bits/stdc++.h>
#define ll unsigned long long
#define R register int
#define inf 0x3f3f3f3f
#define mod 1000000007;
using namespace std;
inline ll read(){
ll s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
return s*w;
}
void put1(){ puts("YES") ;}
void put2(){ puts("NO") ;}
void put3(){ puts("-1"); }
const int manx=2e5+5;
int main()
{
ll p=read();
while(p--)
{
string s;
cin>>s;
ll ans=0;
ll n=s.size();
for(int i=0;i<n;i++)
{
ll x=s[i]-'0';
if(x==1) ans++; //如果当前为1,即本身也符合要求
ll pos=i; // 1后面的第一个位置
while(pos<n-1&&x<=pos-i+1)
//pos<n-1是防止字符串越界 当x大于pos-i+1的时候所以就算计算后面的位置也无法满足条件
{
pos++; //指针后移
x=(x<<1)+s[pos]-'0'; //指针后移 更新x的值 二进制 所以*2
if(x>=1&&x<=pos-i+1) ans++; //如果x>=1才有可能符合条件
}
while(i<n&&s[i]=='0') i++; //直接找到下一个1的位置
}
cout<<ans<<endl;
}
return 0;
}