洛谷P4824题解

题面

题意:给出字符串 s 和 t,每次操作将 s 中出现的第一个 t 删去,直到不能删为止。求最后的串。
|s|<=1e6


题解:hash 做法。(此题也有 kmp 和权值线段树做法)
因为涉及到删除操作,所以我们要动态的实现这个过程。所以考虑开一个栈来存储当前留下的字符。
然后每有一个字符入栈,就拿当前栈顶的 hash 值来算现在的 hash 值。这样就保证了我的栈中每个位置的 hash 值是连续的。
那么就可以用正常字符串 hash 的方法来判断现在栈顶的 |t| 个字符是否和 t 一致了。如果相同,直接栈顶-=|t|,接下来再从新的栈顶开始做就行。
答案就是最后栈中剩下的东西

char s[1000010], t[1000010];
long long adjust = 1, stk[1000010], goal;
int lens, lent, top = 0, ans[1000010];
int main() {
	scanf("%s%s", s+1, t+1);
	lens = strlen(s+1), lent = strlen(t+1);
	for(int i = 1; i <= lent; ++i) adjust = adjust * base % mod;
	for(int i = 1; i <= lent; ++i) goal = (goal * base + t[i] - 'a' + 1) % mod;
	for(int i = 1; i <= lens; ++i) {
		stk[top + 1] = (stk[top] * base + s[i] - 'a' + 1) % mod; top++;
		ans[top] = i;
		if(top >= lent && ((stk[top] - stk[top - lent] * adjust % mod) % mod + mod) % mod == goal) top -= lent;
	}
	for(int i = 1; i <= top; ++i) putchar(s[ans[i]]);
	return 0;
}
posted @ 2023-05-05 10:03  1358id  阅读(21)  评论(0编辑  收藏  举报