正题
题目链接:http://noip.ybtoj.com.cn/contest/105/problem/2
题目大意
一个010101串,qqq个询问,每次询问有多少个长度为mmm的子串010101个数与给出的010101串TTT相同
解题思路
因为询问串的总长与nnn同级,所以考虑根号分治
将询问的TTT串长度分为两部分。对与大于n\sqrt nn的,我们直接暴力,因为这样的串的个数不会超过L\sqrt LL个,所以时间复杂度是O(nL)O(n\sqrt L)O(nL)的。对与小于n\sqrt nn的,我们提前预处理,时间复杂度O(nn)O(n\sqrt n)O(nn)
所以时间复杂度是O(nn)O(n\sqrt n)O(nn)的
codecodecode
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=2e5+10;
int n,m,a[N],v[510][N];
char s[N],t[N];
int main()
{
// freopen("similar.in","r",stdin);
// freopen("similar.out","w",stdout);scanf("%s",s+1);n=strlen(s+1);scanf("%d",&m);for(int i=1;i<=n;i++)a[i]=a[i-1]+s[i]-'0';int T=sqrt(n);for(int i=1;i<=T;i++)for(int j=0;j<=n-i;j++)v[i][a[j+i]-a[j]]++;while(m--){scanf("%s",t+1);int l=strlen(t+1),k=0;for(int i=1;i<=l;i++)k+=(t[i]-'0');if(l>T){int ans=0;for(int i=0;i<=n-l;i++)ans+=((a[i+l]-a[i])==k);printf("%d\n",ans);}else printf("%d\n",v[l][k]);}
}