CF1005E1 学习笔记
本蒟蒻的第四篇题解,求管理员通过 qwq。
题意
中位数是什么就不用我说了给定一个数组 \(a\),求中位数等于 \(m\) 的区间个数。
思路
令 \(n\) 为区间长,考虑何时中位数才能为 \(m\):
- 当 \(n \equiv 0 \pmod{2}\) 时,当且仅当大于等于 \(m\) 的个数比小于等于 \(m\) 的个数相等时中位数是 \(m\);
- 当 \(n \equiv 1 \pmod{2}\) 时,当且仅当大于等于 \(m\) 的个数比小于等于 \(m\) 的个数多一时中位数是 \(m\)。
令在 \([1,i]\) 区间内小于等于 \(m\) 的个数为 \(p1_i\),大于等于 \(m\) 的个数为 \(p2_i\),\(l\) 为左端点,\(r\) 为右端点,则有
\[\begin{cases}
p1_r-p1_l=p2_r-p2_l & r-l+1 \equiv 0 \pmod{2}\\
p1_r-p1_l+1=p2_r-p2_l & r-l+1 \equiv 1 \pmod{2}
\end{cases}
\]
让式子变得美观就是
\[\begin{cases}
p1_r-p2_r=p1_l-p2_l & r-l+1 \equiv 0 \pmod{2}\\
p1_r-p2_r+1=p1_l-p2_l & r-l+1 \equiv 1 \pmod{2}
\end{cases}
\]
用 map 存差值计算即可。
代码
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <iterator>
#include <map>
#include <unordered_map>
#include <queue>
#include <string>
#include <cstring>
#include <set>
#include <bitset>
#include <unordered_set>
#include <vector>
#include <deque>
#include <iomanip>
#include <fstream>
#include <sstream>
#include <list>
#include <array>
#include <iterator>
#include <cmath>
#include <new>
#include <random>
#include <cfloat>
#include <cstdlib>
#include <climits>
#include <numeric>
#include <complex>
#include <ctime>
#include <chrono>
#include <thread>
#include <mutex>
#include <future>
#include <exception>
#include <stdexcept>
#include <cstdint>
#include <cassert>
#include <stack>
#include <cctype>
#define Ofile(s) freopen(s".in", "r", stdin), freopen (s".out", "w", stdout)
#define Cfile(s) fclose(stdin), fclose(stdout)
#define fast ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); // 缺省源
#define maxn 100005 // 好习惯
#define int long long // 防溢出
using namespace std;
int n, m, ans, now;
int a[maxn], p1[maxn], p2[maxn];
map <int, int> mp;
signed main() {
#ifndef ONLINE_JUDGE
// Ofile("");
// Cfile("");
#endif
fast;
cin >> n >> m;
for (int i = 1; i <= n; i++)
cin >> a[i];
for (int i = 1; i <= n; i++)
if (a[i] == m)
now = i; // 标记一下 m 的位置
mp[0] = 1; // 坑
for (int i = 1; i <= n; i++)
p1[i] += p1[i - 1] + (a[i] <= m), p2[i] += p2[i - 1] + (a[i] >= m); // 统计两个数组
for (int i = 1; i < now; i++)
++mp[p1[i] - p2[i]]; // 统计差值
for (int i = 1; i <= n; i++)
ans += mp[p1[i] - p2[i]] + mp[p1[i] - p2[i] + 1];
return cout << ans, 0;
}

浙公网安备 33010602011771号