必须要记住字符串很好卡一不小心就O(n²),别问我为什么这么说.....QAQ
这题首先满足位数与字母两个限制,那么我们*分大块?分小块,求各块hash值,同时预处理出来每个字符串的前缀hash这样就可以O(1)对比了(千万不要忘记hash字符串对比的功能,我在考试的时候一脑抽就忘了......)
#include#include #include #include #define hash(a) Hash[a+2]using namespace std;typedef unsigned long long ULL;const ULL k=131;ULL Std[15][15],Hash[100030],tool[100030];int len,lon[130],l[15][15],z[130],y[130],L,R,lo[130],n;char s[100030];bool Over[130];inline bool blabla(int start,int num){ for(int i=1;i<=Std[num][0];i++) if((ULL)(hash(start+l[num][i]-1)-hash(start-1))==(ULL)Std[num][i]*tool[start]) start+=l[num][i]+1; else return 0; return 1;}void pre(){ tool[0]=1; for(int i=1;i<=100000;i++)tool[i]=tool[i-1]*k; scanf("%s",s); R=len=strlen(s); L=-1; Std[0][0]=1; Std[1][0]=1; for(int i=0;i y[i]+1) { Over[i]=1; continue; } hash(0)=s[0]; for(int j=1;j y[i])break; if(blabla(j,had)) { j+=lo[had]-1; had++; if(had==Std[0][0])break; } } if(had!=Std[0][0]) Over[i]=1; }}void print(){ for(int i=1;i<=n;i++) { if(Over[i]) printf("NO\n"); else printf("YES\n"); }}int main(){ pre(); work(); print(); return 0;}