我是菜鸡 勿喷
我是先遍历一遍,用优先队列(大顶堆)去存储字符串中等于字符a的下标,并且记录a的前面有几个a; 然后从后边去遍历字符串中等于字符b的字符,并且判断优先队列中下标最大的和当前b之间的子串满不满足长度大于等于k,如果满足就加上之前所有的a,否则删去优先队列中的最大值,直到优先队列为空或者满足条件。
大佬们的一个前缀和,给我干哭了!!!
//AC代码如下:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define endl '\n'
ll k,ans=0;
string t;
char a,b;
struct y{
ll i,num;//i 储存下标 num储存数量
bool operator<(const y &b)const{
return i<b.i;
}
};
int main(){
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
cin>>k>>t>>a>>b;
priority_queue<y>q;
ll cnt=0;//cnt是计数器
// 储存a
for(ll i=0;i<t.size();i++){
if(t[i]==a){
cnt++;
q.push({i,cnt});
}
}
//从后边枚举b
for(ll i=t.size()-1;i>=0||q.empty();i--){
if(q.empty())break;
//满足条件
if(t[i]==b){
if(i-q.top().i+1>=k){
y b=q.top();
ans+=b.num;
}else{
//不满足条件
while(i-q.top().i+1<k&&!q.empty()){
q.pop();
}
if(i-q.top().i+1>=k){
y b=q.top();
ans+=b.num;
}
}
}
}
cout<<ans;
return 0;
}