CF #299 div1 B. Tavas and Malekas KMP-next数组

题目链接: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 }
View Code

 

posted @ 2016-03-05 18:39  活在夢裡  阅读(224)  评论(0编辑  收藏  举报