解法:双指针或者二分,最主要的是能想到,先把出现c1字符和c2字符的下标先存起来,然后枚举c1出现的每个坐标,用双指针或者二分去找到c2中第一个符合条件的下标,因为下标存储是递增的,当前的下标符合了,后面的肯定也就符合了,就可以总数-第一个符合条件的下标。
#include<iostream>
#include<vector>
using namespace std;
//先用两个数组存储 c1,c2出现的下标,枚举每个c1下标
// 二分出c2数组中 第一个符合条件的的位置 然后c2数组大小减掉符合条件的位置
vector<int>st,ed;
//双指针做法
long long getRes(int k)
{
long long res=0;
for(int i=0,j=0;i<st.size();i++)
{
while(j<ed.size()&&ed[j]<st[i]+k-1)j++;
if(ed[j]>=st[i]+k-1)res+=ed.size()-j;
}
return res;
}
int main()
{
int k;
string str;
char c1, c2;
cin>>k>>str>>c1>>c2;
for(int i=0;i<str.size();i++)
{
if(str[i]==c1)st.push_back(i);
if(str[i]==c2)ed.push_back(i);
}
// long long res=0;
// for(int i=0;i<st.size();i++)
// {
// int t = st[i] + k - 1;
// int l = 0, r = ed.size()-1;
// // 二分出c2数组中 第一个符合条件的的位置
// while(l<r)
// {
// int mid = (l+r)>>1;
// if(ed[mid]>=t)r=mid;
// else l=mid+1;
// }
// if(ed[l]>=t)res += ed.size()-l;
// }
long long res2 = getRes(k);
//cout<<res<<" "<<res2<<" "<<endl;
cout<<res2;
return 0;
}