注意到只是要求以b为中位数的连续子序列,那么a[i]的大小就不重要了,只需要区分三种情况
a[i] > b 就将a[i] = 1
a[i] == b 就将a[i] = 0
a[i] < b 就将a[i] = -1
又由于这个连续子序列长度为奇数 则在更改数值后满足题意的连续子序列的和就为0,这时候就好做了,记录a[i] = 0的位置,从这个点往前求后缀和,往后求前缀和,由于此处的和可能会出现复数,所以此处我采用map去记录两边出现的值的次数,则所有满足条件的子序列的个数就是对mp1[i] * mp2[-i]求和
注意,此处依旧少了一些情况
1)只选取左边和为0的情况
2)只选取右边和为0的情况
3)左边和右边都不选取的情况
代码如下

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 100010;
int a[N], p1[N], p2[N];
int main ()
{
  ios::sync_with_stdio(0), cin.tie(0);
  int n, b, pos;cin >> n >> b;
  for (int i = 1;i <= n; ++ i) {
    cin >> a[i];
    if (a[i] < b) a[i] = -1;
    else if (a[i] > b) a[i] = 1;
    else {
      a[i] = 0;
      pos = i;
    }
  }
  for (int i = pos;i <= n; ++ i) p2[i] = p2[i - 1] + a[i];
  for (int i = pos;i >= 1; -- i) p1[i] = p1[i + 1] + a[i];
  map<int, int> mp1, mp2;
  for (int i = 1;i < pos; ++ i) mp1[p1[i]] ++;
  for (int i = pos + 1;i <= n; ++ i) mp2[p2[i]] ++;
  ll ans = 0;
  for (int i = -1e5;i <= 1e5; ++ i){
    ans += mp1[i] * mp2[-i];
  }
  cout << ans + mp1[0] + mp2[0] + 1 << '\n';
}