原题链接
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 5e5 + 5;
int sut[N][20];
int sum[N];
struct Node {
int o, l, r, w;
bool operator < (const Node &he) const {
return sum[this->o] - sum[this->w] < sum[he.o] - sum[he.w];
}
inline int get() {
return sum[this->o] - sum[this->w];
}
};
template<typename T, typename _Compare = less<T> >
class Heap {
T *tr;
int size, temp;
_Compare cmp;
public :
Heap(int MaxSize) {
tr = new T[MaxSize * 2];
size = 0;
}
inline void push(const T &vue) {
tr[++ size] = vue;
}
inline void down(int u) {
while ((temp = u << 1) <= size) {
if (temp < size && cmp(tr[temp], tr[temp | 1])) ++ temp;
if (cmp(tr[u], tr[temp])) swap(tr[u], tr[temp]), u = temp;
else break;
}
}
inline void up(int u) {
while ((temp = u >> 1) && cmp(tr[temp], tr[u]))
swap(tr[temp], tr[u]), u = temp;
}
inline void insert(const T &vue) {
tr[++ size] = vue;
up(size);
}
inline void build() {
for (int i = size >> 1; i; -- i) down(i);
}
inline T pop() {
T top = tr[1];
tr[1] = tr[size --];
down(1);
return top;
}
};
char Log2[N];
int query(int x, int y) {
return sum[x] < sum[y] ? x : y;
}
int MaxElement(int _L, int _R) {
int L2_ = Log2[_R - _L + 1];
return query(sut[_L][L2_], sut[_R + 1 - (1 << L2_)][L2_]);
}
void GetST(int Len) {
for (int i = 2; i <= Len; ++ i) Log2[i] = Log2[i >> 1] + 1;
int Len_1 = Len + 1;
for (int i = 1, k = 0; i <= Log2[Len]; ++ i, ++ k) {
int Mlie = 1 << i, Mlke = 1 << k;
for (int j = 0; j + Mlie <= Len_1; ++ j) {
//sut[j][i] = max(sut[j][k], sut[j + Mlke][k]);
sut[j][i] = query(sut[j][k], sut[j + Mlke][k]);
}
}
}
signed main() {
int n, k, L, R, num;
long long res = 0;
scanf("%d %d %d %d", &n, &k, &L, &R);
for (int i = 1; i <= n; ++ i) scanf("%d", &num), sum[i] = sum[i - 1] + num, sut[i][0] = i;
GetST(n);
Heap<Node> Q(max(n, k));
for (int i = L; i <= n; ++ i) {
int r = i - L, l = max(0, i - R);
Q.push(Node{i, l, r, MaxElement(l, r)});
}
Q.build();
while (k --) {
Node data = Q.pop();
res += data.get();
if (data.w != data.l) Q.insert(Node{data.o, data.l, data.w - 1, MaxElement(data.l, data.w - 1)});
if (data.w != data.r) Q.insert(Node{data.o, data.w + 1, data.r, MaxElement(data.w + 1, data.r)});
}
return cout << res, 0;
}