24暑假2D

c65555051e494487bdd1702c6dfa9df7.png

using i64 = long long;

template<class T>
void chmax(T& a, T b) {
    if (a < b) {
        a = b;
    }
}

template<class T>
void chmin(T& a, T b) {
    if (a > b) {
        a = b;
    }
}

int ctz(unsigned long long x) {
    if (x == 0) return 64;
    int n = 0;
    if ((x & 0xFFFFFFFF) == 0) { n += 32; x >>= 32; }
    if ((x & 0xFFFF) == 0) { n += 16; x >>= 16; }
    if ((x & 0xFF) == 0) { n += 8; x >>= 8; }
    if ((x & 0xF) == 0) { n += 4; x >>= 4; }
    if ((x & 0x3) == 0) { n += 2; x >>= 2; }
    if ((x & 0x1) == 0) { n += 1; }
    return n;
}

int clz(unsigned long long x) {
    if (x == 0) return 64;
    int n = 0;
    if ((x & 0xFFFFFFFF00000000) == 0) { n += 32; x <<= 32; }
    if ((x & 0xFFFF000000000000) == 0) { n += 16; x <<= 16; }
    if ((x & 0xFF00000000000000) == 0) { n += 8; x <<= 8; }
    if ((x & 0xF000000000000000) == 0) { n += 4; x <<= 4; }
    if ((x & 0xC000000000000000) == 0) { n += 2; x <<= 2; }
    if ((x & 0x8000000000000000) == 0) { n += 1; }
    return n;
}

int _log2(unsigned long long x) {
    return x == 0 ? -1 : 63 - clz(x);
}


template<class T, class Cmp = std::less<T>>
struct RMQ {
    const Cmp cmp = Cmp();
    static constexpr unsigned B = 64;
    using u64 = unsigned long long;
    int n;
    std::vector<std::vector<T>> a;
    std::vector<T> pre, suf, ini;
    std::vector<u64> stk;
    RMQ() {}
    RMQ(const std::vector<T>& v) {
        init(v);
    }
    void init(const std::vector<T>& v) {
        n = v.size();
        pre = suf = ini = v;
        stk.resize(n);
        if (!n) {
            return;
        }
        const int M = (n - 1) / B + 1;
        const int lg = _log2(M);
        a.assign(lg + 1, std::vector<T>(M));
        for (int i = 0; i < M; i++) {
            a[0][i] = v[i * B];
            for (int j = 1; j < B && i * B + j < n; j++) {
                a[0][i] = std::min(a[0][i], v[i * B + j], cmp);
            }
        }
        for (int i = 1; i < n; i++) {
            if (i % B) {
                pre[i] = std::min(pre[i], pre[i - 1], cmp);
            }
        }
        for (int i = n - 2; i >= 0; i--) {
            if (i % B != B - 1) {
                suf[i] = std::min(suf[i], suf[i + 1], cmp);
            }
        }
        for (int j = 0; j < lg; j++) {
            for (int i = 0; i + (2 << j) <= M; i++) {
                a[j + 1][i] = std::min(a[j][i], a[j][i + (1 << j)], cmp);
            }
        }
        for (int i = 0; i < M; i++) {
            const int l = i * B;
            const int r = std::min(static_cast<unsigned>(n), l + B);
            u64 s = 0;
            for (int j = l; j < r; j++) {
                while (s && cmp(v[j], v[_log2(s) + l])) {
                    s ^= 1ULL << _log2(s);
                }
                s |= 1ULL << (j - l);
                stk[j] = s;
            }
        }
    }
    T operator()(int l, int r) {
        if (l / B != (r - 1) / B) {
            T ans = std::min(suf[l], pre[r - 1], cmp);
            l = l / B + 1;
            r = r / B;
            if (l < r) {
                int k = _log2(r - l);
                ans = std::min({ ans, a[k][l], a[k][r - (1 << k)] }, cmp);
            }
            return ans;
        }
        else {
            int x = B * (l / B);
            return ini[ctz(stk[r - 1] >> (l - x)) + l];
        }
    }
};

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);

    int n, x, y;
    std::cin >> n >> x >> y;

    std::vector<int> a(n);
    for (int i = 0; i < n; i++) {
        std::cin >> a[i];
    }
    std::sort(a.begin(), a.end());

    const int s = x + y;

    std::vector<i64> dp(s + 1);
    for (auto a : a) {
        RMQ<i64, std::greater<>> rmq(dp);
        std::vector<i64> ndp(s + 1);
        for (int p = 0; p <= s; p++) {
            int q = s - p;
            int lo = 0, hi = std::min(p + 1, q);
            while (lo < hi) {
                int x = (lo + hi) / 2;
                if (dp[p - x] + a < dp[p + x + 1]) {
                    hi = x;
                }
                else {
                    lo = x + 1;
                }
            }
            const int m = lo;
            i64 res = 0;
            if (0 < m) {
                chmax(res, rmq(p + 1, p + m + 1));
            }
            if (m <= p) {
                chmax(res, rmq(0, p - m + 1) + a);
            }
            ndp[p] = res;
        }
        dp = std::move(ndp);
    }

    std::cout << dp[x] << "\n";

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值