CF1217C The Number Of Good Substrings

该博客探讨了一种处理字符串的方法,特别是在长度不超过2e5的情况下。通过预处理找到字符串中首次出现'1'的位置,然后枚举左端点计算符合特定条件的子串数量。文章涉及动态规划和字符串算法,重点在于优化和效率。
摘要由CSDN通过智能技术生成

这题的关键点是字符串的长度不超过2e5

所以对于一个“好”的字符串,抛出去它的前导0,它的长度不会超过17 (log(2e5))

然后直接考虑枚举左端点,统计右端点有多少个符合题意的

在这之前要先预处理 nxt 数组,nxt[i] 表示在 i ~ n 中从左往右数第一次出现‘1’的位置

 

这样对于一个左端点 i ,就令j = nxt[i],向右暴力枚举并计算当前字符串的数值判断即可,一旦数值超过2e5就break

 

 

 

#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define db double
#define rep(x,a,b) for(int x=(a);x<=(b);x++)
#define per(x,a,b) for(int x=(a);x>=(b);x--)
#define reP(x,a,b) for(int x=(a);x<(b);x++)
#define Per(x,a,b) for(int x=(a);x>(b);x--)
#define scf(a) scanf("%d",&a)
#define scfll(a) scanf("%lld",&a)
#define scfdb(a) scanf("%lf",&a)
#define ptf(a) printf("%d",a)
#define ptfll(a) printf("%lld",a)
#define ptfdb(x,a) printf("%.xlf",a)
#define ptfsp(a) printf("%d ",a)
#define ptfllsp(a) printf("%lld ",a)
#define ptfdbsp(x,a) printf("%.xlf ",a)
#define pli(a,b) make_pair(a,b)
#define pb push_back
#define el puts("")
#define FS first
#define SE second
#define PI acos(-1)
/*ios::sync_with_stdio(false);
freopen("in.txt","r",stdin);
freopen("1.out","w",stdout);*/
using namespace std;
const ll mod=998244353;
const int maxn=2e5+5;
char s[maxn];
int nxt[maxn];
int main(){
    int T;scf(T);
    while(T--){
        scanf("%s",s+1);
        int n=strlen(s+1);
        s[n+1]='1';
        per(i,n+1,1){
            if(s[i]=='1') nxt[i]=i;
            else nxt[i]=nxt[i+1];
        }
        int ans=0;
        rep(i,1,n){
            int sum=1;
            int j=nxt[i];
            while(j<=n){
                if(sum==j-i+1) ans++;
                sum=(sum<<1)+s[j+1]-'0';
                j++;
                if(sum>2e5) break;
            }
        }
        ptf(ans);el;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值