洛谷·bzoj·Censoring 审查(silver)

探讨了一种算法,用于从一个长字符串中反复移除特定子串,直至该子串不再存在。采用栈和字符串哈希技术进行高效处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

初见安~这里是传送门:洛谷P4824 & bzoj P3942

题意翻译

Farmer John为他的奶牛们订阅了Good Hooveskeeping杂志,因此他们在谷仓等待挤奶期间,可以有足够的文章可供阅读。不幸的是,最新一期的文章包含一篇关于如何烹制完美牛排的不恰当的文章,FJ不愿让他的奶牛们看到这些内容。

FJ已经根据杂志的所有文字,创建了一个字符串 SS ( SS 的长度保证不超过 10^6106 ),他想删除其中的子串 TT ,他将删去 SS 中第一次出现的子串 TT ,然后不断重复这一过程,直到 SS 中不存在子串 TT 。

注意:每次删除一个子串后,可能会出现一个新的子串 TT (说白了就是删除之后,两端的字符串有可能会拼接出来一个新的子串 TT )。

输入格式:第一行是字符串 SS ,第二行输入字符串 TT ,保证 SS 的长度大于等于 TT 的长度, SS和 TT 都只由小写字母组成。

输出格式:输出经过处理后的字符串,保证处理后的字符串不会为空串。

Translated by @StudyingFather

题目描述

Farmer John has purchased a subscription to Good Hooveskeeping magazine for his cows, so they have plenty of material to read while waiting around in the barn during milking sessions. Unfortunately, the latest issue contains a rather inappropriate article on how to cook the perfect steak, which FJ would rather his cows not see (clearly, the magazine is in need of better editorial oversight).

FJ has taken all of the text from the magazine to create the string SS of length at most 10^6 characters. From this, he would like to remove occurrences of a substring TT to censor the inappropriate content. To do this, Farmer John finds the first occurrence of TT in SS and deletes it. He then repeats the process again, deleting the first occurrence of TT again, continuing until there are no more occurrences of TT in SS. Note that the deletion of one occurrence might create a new occurrence of TT that didn't exist before.

Please help FJ determine the final contents of SS after censoring is complete.

输入格式

The first line will contain SS. The second line will contain TT. The length of TT will be at most that of SS, and all characters of SS and TT will be lower-case alphabet characters (in the range a..z).

输出格式

The string SS after all deletions are complete. It is guaranteed that SS will not become empty during the deletion process.

输入 

whatthemomooofun
moo

输出 

whatthefun

题解

这个题说白了就是给你个字符串S,并且 不断去掉子串T,每次去掉过后两端的字符会接起来,输出最后不存在子串T的字符串。

很明显的一点是,我们如果想到了如何模拟“接起来”这个动作,这个问题也就迎刃而解了。所以可以用栈来维护——不断往里面扔s中的字符,如果出现t了,那就不断pop或者top--

再者问题就是如何判定出现t串了。这里的方法有很多,可以在栈里面边扔边KMP。本狸比较菜,就用字符串hash匹配的……【时间是KMP的三倍……但是可以稳过】。

上代码——

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#define maxn 1000005
using namespace std;
typedef long long ll;
const int p = 13331, q = 998244353;
int read() {
	int x = 0, f = 1, ch = getchar();
	while(!isdigit(ch)) {if(ch == '-') f = -1; ch = getchar();}
	while(isdigit(ch)) x = (x << 1) + (x << 3) + ch - '0', ch = getchar();
	return x * f;
}

char s[maxn], t[maxn], stc[maxn];
int top = 0;
ll hash[maxn], T;
ll power(ll a, ll b) {//这里是个快速幂 
	ll ans = 1;
	while(b) {
		if(b & 1) ans = ans * a % q;
		b >>= 1, a = a * a % q;
	}
	return ans;
}

signed main() {
	scanf("%s%s", s + 1, t + 1);
	int lens = strlen(s + 1), lent = strlen(t + 1);
	for(int i = 1; i <= lent; i++) T = (T * p + t[i] - 'a') % q;//预处理出t的hash值 
	
	for(int i = 1; i <= lens; i++) {
		stc[++top] = s[i];//往stack里扔字符 
		hash[top] = (hash[top - 1] * p + s[i] - 'a') % q;//处理出以当前字符结尾的hash值 
		if(top >= lent && (hash[top] - hash[top - lent] * power(p, lent) % q + q) % q == T) //如果出现了t,匹配上了 
			for(int j = 1; j <= lent; j++) top--;//那就top--,pop出去 
	}
	
	for(int i = 1; i <= top; i++) printf("%c", stc[i]);
	return 0;
}
/*
whatthemomooofun
moo
*/

迎评:)
——End——

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值