class Solution {
  public int countSubarrays(int[] nums, int k) {
    final int INDEX = find(nums, k);
    int ans = 0;
    Map<Integer, Integer> count = new HashMap<>();
    for (int i = INDEX, balance = 0; i >= 0; --i) {
      if (nums[i] < k)
        --balance;
      else if (nums[i] > k)
        ++balance;
      count.merge(balance, 1, Integer::sum);
    }
    for (int i = INDEX, balance = 0; i < nums.length; ++i) {
      if (nums[i] < k)
        --balance;
      else if (nums[i] > k)
        ++balance;
      // The subarray that has balance == 0 or 1 having median equal to k.
      // So, add count[0 - balance] and count[1 - balance] to `ans`.
      ans += count.getOrDefault(-balance, 0) + count.getOrDefault(1 - balance, 0);
    }
    return ans;
  }
  private int find(int[] nums, int k) {
    for (int i = 0; i < nums.length; ++i)
      if (nums[i] == k)
        return i;
    throw new IllegalArgumentException();
  }
}