题目链接:http://codeforces.com/contest/536/problem/B
一个原始字符串,一个未知字符串,每一次从pos[i]开始覆盖未知字符串,问最后字符串的形式,以及判断过程中是否有矛盾。
过程中pos是升序的,所以如果任意连续两次操作,如果覆盖范围不重叠,则没事,否则需要判断原始字符串某一个后缀是否同时也是前缀。这个可以用next数组,z函数,后缀数组等计算。
1 #include <iostream> 2 #include <vector> 3 #include <algorithm> 4 #include <string> 5 #include <string.h> 6 #include <stdio.h> 7 #include <math.h> 8 #include <stdlib.h> 9 #include <queue> 10 #include <stack> 11 #include <map> 12 #include <set> 13 14 using namespace std; 15 16 const int N=1e6+12345; 17 char s[N]; 18 bool valid[N]; 19 int next[N]; 20 void getNext(char *word,int n=0){ 21 n=(n==0)?strlen(word):n; 22 memset(next,0,sizeof(next)); 23 int i,j; 24 for (i=1;i<n;i++){ 25 j=i; 26 while (j){ 27 j=next[j]; 28 if (word[i]==word[j]){ 29 next[i+1]=j+1; 30 break; 31 } 32 } 33 } 34 } 35 int pos[N]; 36 int main () { 37 int n,c; 38 scanf("%d %d",&n,&c); 39 scanf("%s",s); 40 int m=strlen(s); 41 getNext(s,m); 42 for (int i=m;i;i=next[i]) 43 valid[i]=true; 44 for (int i=1;i<=c;i++) 45 scanf("%d",pos+i); 46 pos[0]=-m;pos[++c]=n+1; 47 int space=0; 48 bool ok=true; 49 for (int i=1;i<=c;i++) { 50 pos[i]--; 51 if (pos[i-1]+m>pos[i]) { 52 if (!valid[m-pos[i]+pos[i-1]]) 53 ok=false; 54 } 55 else { 56 space+=pos[i]-(pos[i-1]+m); 57 } 58 } 59 if (!ok) 60 cout<<0<<endl; 61 else { 62 long long ret=1; 63 for (int i=1;i<=space;i++) 64 ret=ret*26LL%1000000007; 65 cout<<ret<<endl; 66 } 67 return 0; 68 }