题目链接:
题意:给一个模式串,然后m个匹配串,要求删掉匹配串中的所有存在的模式串,使得余下的串中没有模式串。
数据很大,需要O(N)的算法。。。
首先kmp求出模式串的next数组,然后就是kmp匹配了。
但是我们要注意到是要删尽,如BBUGUG,这个样例是删没了的,因此在kmp匹配的时候,对于每个字符 i,我们需要维护两个值 l 和 r,分别表示 i 的左边的有效字符串的下标和右边有效字符串的下标。同时还要维护一个cur[i]数组,表示位置为 i 的字符的next值。然后如果匹配到一个,把这个删掉标记,重新从这个匹配串的起始点的前一个有效字符开始匹配,同时令k=next[l[i]]。直到没有匹配为止。
1 //STATUS:C++_AC_928MS_4812KB 2 #include3 #include 4 #include 5 #include 6 #include 7 using namespace std; 8 #define mem(a,b) memset(a,b,sizeof(a)) 9 typedef long long LL;10 11 const int N=2000010;12 13 char s[N],p[N];14 int vis[N];15 int next[N];16 int l[N],r[N],cur[N];17 int T,n,m;18 19 void getnext(char *s,int len)20 {21 int j=0,k=-1;22 next[0]=-1;23 while(j =0)k=next[k];38 cur[i]=++k;39 if(k==lenp){40 int end=r[i];41 for(j=lenp;j--;i=l[i])vis[i]=1;42 r[i]=end;l[end]=i;43 k=cur[i];44 }45 }46 }47 48 int main(){49 // freopen("in.txt","r",stdin);50 int i,j,lenp,lens;51 while(~scanf("%d%s",&n,p))52 {53 getchar();54 lenp=strlen(p);55 getnext(p,lenp);56 while(n--){57 gets(s);58 lens=strlen(s);59 getw(lens,lenp);60 for(i=j=0;i