1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| #include <algorithm> #include <cstdio> #include <queue> const int N = 500010; int n; int sum[N]; int log_2[N], f[N][19]; void Init() { for (int i = 2; i <= n; i++) log_2[i] = log_2[i >> 1] + 1, f[i][0] = i; int h = log_2[n]; for (int k = 1; k <= h; k++) for (int i = 1; i + (1 << k) - 1 <= n; i++) { const int &left = f[i][k - 1], &right = f[i + (1 << k - 1)][k - 1]; f[i][k] = sum[left] < sum[right] ? right : left; } } int Query(const int l, const int r) { int k = log_2[r - l + 1]; const int &left = f[l][k], &right = f[r - (1 << k) + 1][k]; return sum[left] < sum[right] ? right : left; } struct Chord { int st, l, r, pos; Chord(int __st, int __l, int __r) : st(__st), l(__l), r(__r) { pos = Query(l, r); } const bool operator<(const Chord &b) const { return sum[pos] - sum[st - 1] < sum[b.pos] - sum[b.st - 1]; } }; int main() { int k, l, r; scanf("%d%d%d%d", &n, &k, &l, &r); for (int i = 1; i <= n; i++) { scanf("%d", &sum[i]); sum[i] += sum[i - 1]; } Init(); std::priority_queue<Chord> Q; for (int i = 1; i + l - 1 <= n; i++) Q.push(Chord(i, i + l - 1, std::min(i + r - 1, n))); long long ans = 0; while (k--) { Chord now = Q.top(); Q.pop(); ans += sum[now.pos] - sum[now.st - 1]; if (now.l <= now.pos - 1) Q.push(Chord(now.st, now.l, now.pos - 1)); if (now.pos + 1 <= now.r) Q.push(Chord(now.st, now.pos + 1, now.r)); } printf("%lld\n", ans); return 0; }
|