题意:
给出 的一个排列,统计该排列有多少个长度为奇数的连续子序列的中位数是 。
题解:
先考虑一段区间中位数为 有什么性质:这一段区间内大于 的数和小于 的数一样多,并且包含 。
然后做一个简单的转化,大于 的数记为 ,小于 的数即为 。
那么中位数为 的区间就有:
- 区间包含 所在的位置 ,即区间 满足 。
- 转化后的区间和为 0。
求区间和为 的数量有一个常用的技巧:前缀和。
区间 和为 ,等价于区间 的和与区间 的和相等,即前缀和 。
然后用一个 map<int, int> 保存前缀和为某个值对应的数量。这样从左至右遍历统计就可以了。
这道题还有和包含位置 的限制条件,这样可以将位置 左边的前缀和对应值存入 map,右边的前缀和则用于查找有多少对应的区间左端点,统计答案。
Code
#include <bits/stdc++.h> using namespace std; int n, b; map<int, int> mmp; int main() { cin >> n >> b; bool left = true; long long sum = 0, ans = 0; mmp[sum]++; for(int i = 1; i <= n; i++) { int x; cin >> x; if(x == b) left = false; else sum += x > b ? 1 : -1; if(left) mmp[sum]++; else ans += mmp[sum]; } cout << ans << endl; return 0; }