卧薪尝胆,厚积薄发。
USACO2015FEB SILVER Censoring
Date: Fri Sep 14 23:29:41 CST 2018
In Category:
NoCategory
Description:
有一个两个串,然后从前往后枚举
$S$
串字符往
$U$
串里添加,若
$U$
串后缀为
$T$
,则去掉这个后缀继续流程,求最后的串。
$1\le len\le 1000000$
Solution:
考虑
$KMP$
算法的过程,对于模板串,实际上就是每次在后面加一个字符并求出它的
$nxt$
值,也即是说
$KMP$
是支持在末尾加入,在末尾删除的,对于文本串,实际上也是每次加一个字符,然后和模板串匹配,所以也是支持末尾加入的,那就可以维护一个栈,记录在文本串匹配到某一位的时候,模板串匹配到了哪里,每次在上一次匹配的位置往后继续匹配,如果找到了,就弹
$l$
次栈即可。
用
$KMP$
算法的复杂度证明可以证明这是
$O(n)$
的。
Code:
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
#define rint register int
#define MAXL 1000010
char s[MAXL],t[MAXL];
int l1,l2;
int nxt[MAXL];
int st[MAXL],p[MAXL],top = 0;
int main()
{
scanf("%s%s",s + 1,t + 1);
l1 = strlen(s + 1);l2 = strlen(t + 1);
for(rint i = 2,j = 0;i <= l2;++i)
{
while(j && t[j + 1] != t[i])j = nxt[j];
if(t[j + 1] == t[i])++j;
nxt[i] = j;
}
for(rint i = 1;i <= l1;++i)
{
st[++top] = s[i];
rint j = p[top - 1];
while(j && s[i] != t[j + 1])j = nxt[j];
if(s[i] == t[j + 1])++j;
p[top] = j;
if(p[top] == l2)top -= l2;
}
for(rint i = 1;i <= top;++i)putchar(st[i]);puts("");
return 0;
}
In tag:
字符串-KMP
Copyright © 2020
wjh15101051
ღゝ◡╹)ノ♡