VMC 沙滩拾贝

沙滩拾贝

image

因为是二进制运算,所以直接考虑二进制位相关。

很容易发现肯定要尽可能保证高位为 1,如果答案中某一位为 1,那么至少要有 m 个数在这一位为 1,才有可能使答案在这一位为 1。

因此从高位到低位扫描,如果某一位存在大于等于 \(m\) 个数符合上述条件,那么把这一位不为 1 的数全部删去(否则可能导致这一位结果变成 0),并把答案的这个二进制位设置为 1。接下来在剩下的数中重复以上操作即可。

代码如下:

#include <bits/stdc++.h>
#define ll long long
using namespace std;
inline int read();
const int N = 1e5 + 5;
int a[N];
bool mk[N];
int main() {
    int n = read(), m = read();
    for (int i = 1; i <= n; ++i) {
        a[i] = read();
    }
    int ans = 0;
    for (int i = 30; i >= 0; --i) {
        int cnt = 0;
        for (int j = 1; j <= n; ++j) {
            if (mk[j]) continue;
            if (a[j] & (1 << i)) {
                ++cnt;
            }
        }
        if (cnt >= m) {
            for (int j = 1; j <= n; ++j) {
                if ((a[j] & (1 << i)) == 0) {
                    mk[j] = 1;
                }
            }
            ans |= 1 << i;
        }
    }
    printf("%d", ans);
    return 0;
}
inline int read() {
    int x = 0;
    char c = getchar();
    bool f = 1;
    while (!isdigit(c))
        f = c ^ 45, c = getchar();
    while (isdigit(c))
        x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
    return f ? x : -x;
}
posted @ 2025-02-18 18:25  Maplisky  阅读(31)  评论(0)    收藏  举报