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;
}
posted @ 2026-02-02 17:49  constexpr_ll  阅读(1)  评论(0)    收藏  举报