1 条题解

  • 0
    @ 2025-9-18 20:54:50

    首发 AC😋

    先求出最多保留的数量,从 l 到 r,可以考虑先排序,去重,再做一个类似 离散化 的操作。

    二分,得到小于等于一个数的前缀数组,可用于之后的 滑动窗口 ,求出窗口内数字的最大数量,用 n 减去就是 需要去除的数量。

    c++代码:

    #include <bits/stdc++.h>
    using namespace std;
    
    int main() {
        int n, siz;
        cin >> n >> siz;
        vector<int> a(n), a_uni;
        for (auto &i : a) {
            cin >> i;
        }
        sort(a.begin(), a.end());
        a_uni.emplace_back(a[0]);
        for (int i = 1; i < n; ++i) {
            if (a[i] != a[i - 1]) {
                a_uni.emplace_back(a[i]);
            }
        }
        int m = a_uni.size();
        int max_bits = siz * 8;
        int max_k = max_bits / n;
        int required_k;
        if (m == 1) {
            required_k = 0;
        } else {
            required_k = 32 - __builtin_clz(m - 1);
        }
        if (1LL * n * required_k <= max_bits) {
            cout << 0;
            return 0;
        }
    
        int K_max;
        if (max_k == 0) {
            K_max = 1;
        } else {
            K_max = 1 << max_k;
        }
        K_max = min(K_max, m);
    
        vector<int> prefix(m);
        for (int i = 0; i < m; ++i) {
            prefix[i] = upper_bound(a.begin(), a.end(), a_uni[i]) - a.begin();
        }
    
        int max_keep = prefix[0];
        for (int i = 0; i <= m - K_max; ++i) {
            int j = i + K_max - 1;
            max_keep = max(max_keep, prefix[j] - prefix[i - 1]);
        }
        cout << n - max_keep;
        return 0;
    }
    
    • 1

    信息

    ID
    501
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    (无)
    递交数
    2
    已通过
    1
    上传者