24暑假2D

c65555051e494487bdd1702c6dfa9df7.png

using i64 = long long;

int count(i64 n) {
	int ans = 0;
	for (int i = 0; i < 64; i++) {
	    if ((n >> i & 1) == 1)ans++;
	}
	return ans;
}
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 custom_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 custom_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 custom_log2(unsigned long long x) {
    return x == 0 ? -1 : 63 - custom_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 = custom_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[custom_log2(s) + l])) {
                    s ^= 1ULL << custom_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 = custom_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[custom_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;
}

 

 

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值