c 【NOIP2017GDKOI模拟1.12】

本文介绍了一种优化字符串匹配的方法,通过预处理部分答案并利用询问串长度限制来提高效率。文章详细描述了解决方案的思路及实现过程,并提供了一个具体的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这里写图片描述
样例输入:
这里写图片描述
100110100
5
11
101
010
10
00

样例输出:
这里写图片描述
1
3
4
5
2

数据范围:
这里写图片描述


思路

比赛时没有注意到所有询问串的长度总和不超过二十万这个条件,然后就只想到暴力。。。。


解法

1.据说有根号级别的解法?%%%%
2.由于询问串的长度总共不超过二十万,那么复杂度会远小于理论复杂度。。。。。
我们先把一部分答案存下来(这里我存了长度300的,300~400应该都行)。
设f[i][j]表示字符串长度为i的区间1的个数有j个的数量,预处理出来。
对于每一个询问,如果询问串的长度<=300,直接输出即可。大于就暴力。
事实证明,跑的似乎比根号的要快。。。。


代码

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<cmath>
#define fo(i,a,b) for(int i=a;i<=b;i++)

using namespace std;

const int maxn=305,len=2*1e5+5;
int f[maxn][maxn],q,ans,sum[len];
char ch[len],c;

int main()
{
    freopen("c.in","r",stdin);
    freopen("c.out","w",stdout);
    scanf("%s",ch+1);
    int tot=strlen(ch+1);
    fo(i,1,tot) {
        sum[i]=sum[i-1];
        if (ch[i]=='1') ++sum[i];
        int pre=max(i-300,1);
        fo(j,pre,i) f[i-j+1][sum[i]-sum[j-1]]++;
    }
    scanf("%d",&q);
    fo(o,1,q){
        ans=0;
        int lenn=0,num=0;
        c=getchar();
        while (c!='0'&&c!='1') c=getchar();
        while (c=='1'||c=='0'){
            ++lenn;
            if (c=='1') ++num;
            c=getchar();
        }
        if (lenn<=300) printf("%d\n",f[lenn][num]);
        else {
            fo(i,lenn,tot)
            if (sum[i]-sum[i-lenn]==num) ++ans;
            printf("%lld\n",ans);
        }
    }
}

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值