牛客 D 无限的韵律源点 (对顶堆+滑动窗口)
思路
本题的重点在于 recent best部分,即指定下标和指定长度的区间 k 最大值,这实际上是区间 k 最值的***版。因此可以选择主席树,划分树等数据结构直接维护。由于本题固定长度的限制,实际上可以借助对顶堆,通过滑动窗口的思想直接维护。开一个小根堆,维护前rb大的值,盛下的维护后ra-rb小的值
可以直接用set替代堆,实现两个部分的维护
代码
#include<iostream>
#include<set>
#include<algorithm>
#include<vector>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
#define x first
#define y second
int main() {
int n, b, ra, rb;
cin >> n >> b >> ra >> rb;
vector<int> nums(n);
for (int i = 0; i < n; i++) cin >> nums[i];
multiset<pii> s, sx;
multiset<pii, greater<pii>> sy;
ll sum1 = 0, sum2 = 0;
ll ans = 0;
for (int i = 0; i < n; i++) {
s.insert({
nums[i],i });
sum1 += nums[i];
while (s.size() > b) {
sum1 -= s.begin()->x;
s.erase(s.begin());
}
if (i >= ra) {
int j