由于是第一次打算法类竞赛所以不太熟悉流程导致该拿分的没拿到,所以写篇博客来警醒自己。
直接说思路吧:
我们可以先将每个c1字符的每个出现位置和c2字符的每个出现位置记录下来,然后通过枚举c1字符的出现位置来用二分查找对应c1字符位置出现时c2字符应该在哪个位置出现。然后求和c2字符出现的总次数去减去枚举每个c1字符时c2字符正确的位置就可以了。
图解:
代码如下:
#include<iostream>
#include<algorithm>
using namespace std;
int nec1[500100];
int c1dx = 0;
int c2dx = 0;
int nec2[500100];
int main()
{
int k;
cin >> k;
string str;
cin >> str;
str = "1" + str;
char c1, c2;
cin >> c1 >> c2;
for (int i = 1; i < str.length(); i++) {
//记录c1字符所有出现的位置
if (str[i] == c1) {
nec1[c1dx] = i;
c1dx++;
}
//记录c2字符所有出现位置
if (str[i] == c2) {
nec2[c2dx] = i;
c2dx++;
}
}
long long ans = 0;
//枚举c1字符出现的位置
for (int i = 0; i < c1dx; i++) {
//二分查找c2字符出现的位置的合法位置
auto dx = lower_bound(nec2, nec2 + c2dx, nec1[i] + k-1);
//没有找到情况
if (dx == nec2 + c2dx)continue;
//找到了
int t = dx - nec2;
//加上总合法个数
ans += c2dx - t;
}
cout << ans << endl;
return 0;
}
若有雷同纯属意外。