SCU 4438 Censor
$KMP$,链表。
将$p$弄成链表,每次匹配到,删掉中间的,继续匹配。
#include<bits/stdc++.h> using namespace std; const int INF = 0x7FFFFFFF; const int mod = 1e9 + 7; const int N = 5e6 + 10; const int M = 1e4 + 1; const double eps = 1e-10; int T,n,m; char w[N],p[N]; int L[N],R[N],h; int lenp,lenw; int t[N]; int nt[N]; void init() { nt[0] = -1; for (int i = 0; w[i]; i++) { int k = nt[i]; while (k >= 0 && w[i] != w[k]) k = nt[k]; nt[i + 1] = k + 1; } } int main() { while(~scanf("%s%s",w,p+1)) { lenp=strlen(p+1); lenw = strlen(w); for(int i=1;i<=lenp;i++) L[i]=i-1,R[i]=i+1; init(); R[0]=1; L[lenp+1] = lenp; t[0]=nt[1]; for (int i = R[0], j = nt[1]; p[i];) { t[i]=j; if (j < 0 || p[i] == w[j]) { i=R[i], j++; if (!w[j]) { int sum=0; for(int u=L[i];;u=L[u]) { if(sum==lenw) { j=t[u]; i=u; if(i==0) i=R[0]; break; } int x=L[u]; int y=R[u]; R[x]=y; L[y]=x; sum++; } } } else j = nt[j]; } for(int i=R[0];i!=lenp+1;i=R[i]) { printf("%c",p[i]); } printf("\n"); } return 0; }