AC日记——背单词 洛谷 P2353
思路:
KMP+统计前缀和优化;
代码:
#include <bits/stdc++.h> using namespace std; #define maxn 1000005 int n,m,air[maxn][11],len_,len,bi[maxn],fail[maxn]; int lit[11],cnt,ans[maxn]; char ch[maxn],T[maxn]; inline void in(int &now) { char Cget=getchar();now=0; while(Cget>'9'||Cget<'0')Cget=getchar(); while(Cget>='0'&&Cget<='9') { now=now*10+Cget-'0'; Cget=getchar(); } } void KMP(int now) { int k=-1,v=0;fail[v]=k; while(v<len_) { if(k==-1||T[v]==T[k]) k++,v++,fail[v]=k; else k=fail[k]; } int i=0;v=0; while(i<=len) { if(v==-1||ch[i]==T[v]) v++,i++; else v=fail[v]; if(v==len_) air[i][now]++,v=fail[v]; } } int main() { in(n),in(m),scanf("%s",ch),len=strlen(ch);int l,r; for(int i=1;i<=n;i++) scanf("%s",T),len_=strlen(T),KMP(i),lit[i]=len_; for(int i=1;i<=len;i++) { for(int v=1;v<=n;v++) air[i][v]+=air[i-1][v]; } for(int i=1;i<=m;i++) { in(l),in(r),cnt=0; for(int v=1;v<=n;v++) { if(l+lit[v]-1<=r) { cnt+=air[r][v]-air[l+lit[v]-2][v]; } } printf("%d\n",cnt); } return 0; }