从前往后依次考虑每个位置的覆盖,前后两次可能会有很大的交集,该交集正好是原串n位置的所有可行前缀失配点。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 1e6 + 10000;
int f[maxn],n,m,ok[maxn],vis[maxn];
char str[maxn];
const int mod = 1000000007;
int get_fail(char* P){
memset(ok,0,sizeof(ok));
int len = strlen(P);
f[0] = f[1] = 0;
for(int i=1;i<len;i++){
int j=f[i];
while(j && P[i]!=P[j]) j=f[j];
if(P[i]==P[j]) j++;
f[i+1] = j;
}
int j = len;
while(j){
ok[j] = 1;
j = f[j];
}
}
int main()
{
scanf("%d %d",&n,&m);
scanf("%s",str);
get_fail(str);
int len = strlen(str);
memset(vis,0,sizeof(vis));
int flag = 1,last = -1;
for(int j=1;j<=m;j++){
int x;
scanf("%d",&x); x--;
if(!flag) continue;
if(last<x){
for(int i=x;i<x+len;i++) {
vis[i] = 1;
}
}
else{
int co = last-x+1;
if(!ok[co]){
flag = 0;
}
else{
for(int i=last+1;i<x+len;i++){
vis[i] = 1;
}
}
}
last = x+len-1;
}
if(flag){
long long res = 1;
for(int i=0;i<n;i++) if(!vis[i]){
res=(res*26)%mod;
}
printf("%I64d\n",res);
}
else printf("0\n");
return 0;
}