【bzoj3942】[Usaco2015 Feb]Censoring
【题目大意】
有一个S串和一个T串,长度均小于1,000,000,设当前串为U串,然后从前往后枚举S串一个字符一个字符往U串里添加,若U串后缀为T,则去掉这个后缀继续流程。
【样例输入】
whatthemomooofun
moo
moo
【样例输出】
whatthefun
【题解】
我能说这是可持久化的kmp吗?(并没有此种术语)
kmp的过程中,用一个栈来存当前U串,如果匹配到了,弹出即可,然后j指针有恢复到历史的状态,这个状态可以用f数组来存。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 #include<ctime> 6 #include<cmath> 7 #include<algorithm> 8 using namespace std; 9 #define MAXN 1000100 10 int n,m,top,stack[MAXN],p[MAXN],f[MAXN]; 11 char a[MAXN],b[MAXN]; 12 int main() 13 { 14 //freopen("cin.in","r",stdin); 15 //freopen("cout.out","w",stdout); 16 scanf("%s",a+1); scanf("%s",b+1); 17 n=strlen(a+1); m=strlen(b+1); 18 for(int i=2,j=0;i<=m;i++) 19 { 20 while(j&&b[j+1]!=b[i]) j=p[j]; 21 if(b[j+1]==b[i]) j++; 22 p[i]=j; 23 } 24 for(int i=1,j=0;i<=n;i++) 25 { 26 j=f[stack[top]]; 27 while(j&&b[j+1]!=a[i]) j=p[j]; 28 if(b[j+1]==a[i]) j++; 29 if(j==m) top-=(m-1); 30 else stack[++top]=i,f[i]=j; 31 } 32 for(int i=1;i<=top;i++) printf("%c",a[stack[i]]); 33 return 0; 34 }