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 63 64 65 66 67 68 69 70 71
| #include <cstdio> #include <queue> #include <algorithm> #define int long long #define GetL(p) (ls[p] ? ls[p] : ls[p] = ++ nodetot) #define GetR(p) (rs[p] ? rs[p] : rs[p] = ++ nodetot)
typedef std::pair<int, int> PII; inline int min(const int x, const int y) {return x < y ? x : y;} const int N = 500005; int a[N], b[N], kth[N], nodetot, n; std::priority_queue<PII> q;
struct Chairman_tree { int sum[N << 5], root[N], ls[N << 5], rs[N << 5], nodetot, x; inline void Update(int k, int p) { x = p, update(root[k] = ++ nodetot, 1, n, root[k - 1]); } inline int Query(int l, int r, int k) { return query(root[r], root[l - 1], 1, n, k); } void make_tree(int p, int x, int y) { if (x == y) return; make_tree(ls[p] = GetL(p), x, x + y >> 1), make_tree(rs[p] = GetR(p), (x + y >> 1) + 1, y); } void update(int p, int l, int r, int root) { if (l == r) {sum[p] = sum[root] + 1; return;} int mid(l + r >> 1); if (mid >= x) update(ls[p] = GetL(p), l, mid, ls[root]), rs[p] = rs[root]; else update(rs[p] = GetR(p), mid + 1, r, rs[root]), ls[p] = ls[root]; sum[p] = sum[ls[p]] + sum[rs[p]]; } int query(int u, int v, int l, int r, int d) { if (l == r) return l; int mid(l + r >> 1), x(sum[ls[u]] - sum[ls[v]]); if (d <= x) return query(ls[u], ls[v], l, mid, d); else return query(rs[u], rs[v], mid + 1, r, d - x); } } Tree;
signed main() { int k, L, R; long long ans(0LL); scanf("%lld%lld%lld%lld", &n, &k, &L, &R); Tree.make_tree(Tree.root[0] = Tree.nodetot = 1, 1, n); for (int i(1); i <= n; ++ i) { int x; scanf("%lld", &x); b[i] = a[i] = a[i - 1] + x; } std::sort(b + 1, b + n + 1); for (int i(1); i <= n; ++ i) Tree.Update(i, std::lower_bound(b + 1, b + n + 1, a[i]) - b); for (int i(1); i + L - 1 <= n; ++ i) { const int st(i + L - 1), ed(min(i + R - 1, n)); q.push(std::make_pair(b[Tree.Query(st, ed, ed - st + 1)] - a[i - 1], i)); kth[i] = ed - st + 1; } while (k --) { PII t(q.top()); q.pop(); ans += t.first; const int i(t.second); const int st(i + L - 1), ed(min(i + R - 1, n)); if (-- kth[i]) q.push(std::make_pair(b[Tree.Query(st, ed, kth[i])] - a[i - 1], i)); } printf("%lld", ans); return 0; }
|