题目大意:给你一个模板串,给你一个 s 串的长度,告诉你 s 串中有 m 个模板串并告诉你,他们的其实位置,
问你这样的 s 串总数的多少,答案对1e9+7取模。
我感觉我英语是不是不行啊,我以为他的意思是他里面一共只有m个匹配串,想着没有其他的匹配串,感觉
好麻烦好麻烦好麻烦啊!!!!!!
思路:最暴力的思路,他给你一个匹配串的位置,你就在s串上更新,如果遇到没有已经被更新而且字符不同时
输出0,然后统计剩下的未知字符的个数x,答案就是 (26^x)%mod。这样可能会超时,我今天学习了一波
KMP(看毛片)算法,这玩意真的有点难理解,以后多理解几遍。
我们可以在更新s串的时候只更新后面没有更新的,然后用kmp扫一遍,看m个匹配串是否都出现过就好了。
#include<bits/stdc++.h> #define ll long long using namespace std; const int N=1e6+5; const ll mod=1e9+7; char s[N],t[N]; int nx[N]; int len1,len2,n,m,w[N],c=0; void get_next() { int k=0; for(int i=1;i<len2;i++) { while(k>0 && t[k]!=t[i]) k=nx[k-1]; if(t[k]==t[i]) k++; nx[i]=k; } } void kmp() { int k=0; for(int i=0;i<n;i++) { while(k>0 && t[k]!=s[i]) k=nx[k-1]; if(t[k]==s[i]) k++; if(k==len2) { if(binary_search(w,w+m,i-k+1)) c++; } } } int main() { cin>>n>>m; scanf("%s",t); len2=strlen(t); for(int i=0;i<n;i++) s[i]=‘?‘; s[n]=‘\0‘; for(int i=0;i<m;i++) scanf("%d",&w[i]),w[i]-=1; sort(w,w+m); m=unique(w,w+m)-w; int last=-1; for(int i=0;i<m;i++) { if(w[i]+len2-1>last) { int start=w[i],dis=0; if(last+1>w[i]) { dis=last+1-w[i];//dis为相对模板串开头的偏移位置。 start=last+1; } for(int j=start;j<=w[i]+len2-1;j++) s[j]=t[j-start+dis]; last=w[i]+len2-1; } } //puts(s); get_next(); kmp(); if(c<m) { puts("0"); return 0; } ll res=0; for(int i=0;i<n;i++) { if(s[i]==‘?‘) res+=1; } ll ans=1; for(int i=1;i<=res;i++) { ans=(ans*(ll)26)%mod; } cout<<ans<<endl; return 0; }
时间: 2024-10-14 02:12:05