YbtOJ#20072-[NOIP2020模拟赛B组Day6]相似子串【根号分治】
生活随笔
收集整理的這篇文章主要介紹了
YbtOJ#20072-[NOIP2020模拟赛B组Day6]相似子串【根号分治】
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
正題
題目鏈接: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]);} }總結
以上是生活随笔為你收集整理的YbtOJ#20072-[NOIP2020模拟赛B组Day6]相似子串【根号分治】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 爱老婆的十句话 爱老婆的句子
- 下一篇: powered by discuz怎么去