VMC 沙滩拾贝
沙滩拾贝

因为是二进制运算,所以直接考虑二进制位相关。
很容易发现肯定要尽可能保证高位为 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;
}
本文来自博客园,作者:Maplisky,转载请注明原文链接:https://www.cnblogs.com/lbh2021/p/18722588

浙公网安备 33010602011771号