[CF914F] Substrings in a String(字符串的暴力匹配)

题目:[CF914F] Substrings in a String

这个题是这样的:

给你一个字符串 s,共有 q 次操作,每个都是下面两种形式的一种。

  • 1 i c:将字符串 s 的第 i 项变为字符 c

  • 2 l r y:求字符串 y 在字符串 s 中以第 l 项为起点,以第 r 项为终点的子串(第 l 和第 r 项)中作为子串出现的次数。

1|s|1051q105|y|105


这个题的做法是这样的:

首先暴力的做法,可以做到 O(1) 的修改操作,以及通过通过枚举左端点然后暴力匹配的 O(|s||y|) 的查询操作。

另一个方向是逐位思考,我们对字符串 y 的每一位来找到左端点,然后对这 |y| 个左端点的集合取交操作,最终集合中的个数就是其答案。

对集合取交的操作,可以想到用位运算 & 来做,那么就可以用 bitset 来做,得到了 O(|s||y|w) 的复杂度。

虽然那个暴力在 |s|=|y| 的时候,可以有 O(|s|) 的复杂度。

参考代码:

#include <bits/stdc++.h>

using namespace std;

const int N  = 1e5;

char s[N + 10], t[N + 10], c;
int n, m, qn;
bitset<N + 10> ans, ch[26];

int main()
{
	cin >> (s + 1) >> qn;
	n = strlen(s + 1);
	for (int i = 1; i <= n; i ++ ) ch[s[i] - 'a'].set(i, true);
	for (int _ = 1, opt, x, y; _ <= qn; _ ++ ) {
		cin >> opt ;
		if (opt == 1) {
			cin >> x >> c;
			ch[s[x] - 'a'].set(x, false);
			ch[(s[x] = c) - 'a'].set(x, true);
		}
		else {
			cin >> x >> y >> t;
			ans.set();
			if ((m = strlen(t)) > y - x + 1) {cout << 0 << '\n'; continue;}
			for (int i = 0; i < m; i ++ ) ans &= (ch[t[i] - 'a'] >> i);
			cout << (ans >> x).count() - (ans >> (y - m + 2)).count() << '\n';
		}
	}
	return 0;
}
posted @   Ciaxin  阅读(5)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示