#include<iostream>
#include<queue>
#define maxn int(5e5+5)
#define logn int(30)
#define ll long long
using namespace std;
ll pre[maxn];
int st[logn][maxn], lg[maxn];
ll n, k, L, R;
priority_queue<ll, vector<ll>, greater<int> > q;
void prest() {
lg[0] = -1;
for(int i = 1; i <= n; i++) {
lg[i] = lg[i>>1]+1;
}
int x, y;
long long ret = 0;
for(int i = 1; i <= lg[n]; i++) {
for(int j = 1; j+(1<<i)-1<=n; j++) {
x = st[i-1][j]; y = st[i-1][j+(1<<(i-1))];
st[i][j] = (pre[x] > pre[y])? x : y;
}
}
}
int RMQ(int lx, int rx) {
int x = lg[rx-lx+1];
return (st[x][lx] > st[x][rx-(1<<x)+1])?
st[x][lx] : st[x][rx-(1<<x)+1];
}
void solve(int x, int lx, int rx) { //左端点,L,R
if(lx>rx) return;
int tx = RMQ(lx, rx);
ll ret = pre[tx]-pre[x-1];
q.push(ret);
while(q.size()>k) q.pop();
if(q.size()==k && q.top() > ret) return;
solve(x, lx, tx-1);
solve(x, tx+1, rx);
}
int main() {
scanf("%lld%lld%lld%lld", &n, &k, &L, &R);
pre[0] = 0;
for(int i = 1; i <= n; i++) {
scanf("%lld", &pre[i]);
pre[i]+=pre[i-1];
st[0][i] = i;
}
prest();
for(int i = 1; i+L-1<= n; i++) {
solve(i, i+L-1, min(n, i+R-1));
}
long long sum = 0;
for(int i = 1; i <= k; i++) {
sum += q.top();
q.pop();
}
printf("%lld\n", sum);
return 0;
}
用小根堆控制答案数,全部求完再输出
开O2后WA#2,感觉是爆了但找不出问题
求调