目录
1.Problem
Before becoming a successful trader William got a university degree. During his education an interesting situation happened, after which William started to listen to homework assignments much more attentively. What follows is the correct formal description of the homework assignment:
You are given a string ss of length nn only consisting of characters "a", "b" and "c". There are qq queries of format (pos,cpos,c), meaning replacing the element of string ss at position pospos with character cc. After each query you must output the minimal number of characters in the string, which have to be replaced, so that the string doesn't contain string "abc" as a substring. A valid replacement of a character is replacing it with "a", "b" or "c".
A string xx is a substring of a string yy if xx can be obtained from yy by deletion of several (possibly, zero or all) characters from the beginning and several (possibly, zero or all) characters from the end.
2.Input
The first line contains two integers nn and qq (1≤n,q≤105)(1≤n,q≤105), the length of the string and the number of queries, respectively.
The second line contains the string ss, consisting of characters "a", "b" and "c".
Each of the next qq lines contains an integer ii and character cc (1≤i≤n)(1≤i≤n), index and the value of the new item in the string, respectively. It is guaranteed that character's cc value is "a", "b" or "c".
3.Output
For each query output the minimal number of characters that would have to be replaced so that the string doesn't contain "abc" as a substring.
4.Examples
4.1input
9 10
abcabcabc
1 a
1 b
2 c
3 a
4 b
5 c
8 a
9 b
1 c
4 a
4.2output
3
2
2
2
1
2
1
1
1
0
5.Code
#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
template<typename T> bool chkmax(T &x,T y){return x<y?x=y,1:0;}
template<typename T> bool chkmin(T &x,T y){return x>y?x=y,1:0;}
int readint(){
int x=0,f=1; char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int n,q;
char s[100005];
int is_abc[100005] = {0}; // 存储每个位置是否为"abc"子串
int check(int i){
if(i+2>n) return 0;
return s[i]=='a'&&s[i+1]=='b'&&s[i+2]=='c';
}
int main(){
n=readint(); q=readint();
scanf("%s",s+1);
// 预处理,计算每个位置是否为"abc"子串
for(int i=1; i<=n-2; i++) {
is_abc[i] = check(i);
}
int cnt=0;
for(int i=1; i<=n-2; i++) cnt += is_abc[i];
while(q--){
int i; char ch;
i=readint(); ch=getchar();
while(ch!='a'&&ch!='b'&&ch!='c') ch=getchar();
// 更新is_abc数组
if(is_abc[i]) cnt--;
if(i-1>1 && is_abc[i-1]) cnt--;
if(i-2>1 && is_abc[i-2]) cnt--;
s[i]=ch;
if(is_abc[i]) cnt++;
if(i-1>1 && is_abc[i-1]) cnt++;
if(i-2>1 && is_abc[i-2]) cnt++;
printf("%d\n",cnt);
}
return 0;
}
6.Conclusion
上面的代码实现了一个程序,其核心逻辑如下所述:
1.定义了一些宏和类型别名,如fi、se、mp、pb等,以及模板函数chkmax和chkmin用于比较和更新变量的最大值和最小值。
2.实现了readint函数用于读取输入的整数。
3.在主函数中,读取整数n和q,并使用scanf函数读取字符串s。
4.进行预处理,通过循环遍历字符串s,调用check函数检查每个位置是否为"abc"子串,并将结果存储在is_abc数组中。
5.初始化计数器cnt为0,并通过循环遍历is_abc数组,统计初始时满足条件的子串数量。
6.进行查询处理,循环进行q次查询操作。
7.对于每次查询,读取查询位置i和字符ch,并通过循环和条件分支更新is_abc数组和计数器cnt。
8.最后,输出每次查询操作后满足特定条件的子串数量cnt。该代码的核心逻辑是根据输入的字符串s和查询操作,通过预处理提前计算并存储每个位置是否为"abc"子串的状态,然后根据查询操作的要求更新状态并计数满足条件的子串数量。整体上,该代码实现了对字符串的查询和操作。