题意
给出一个序列,截取其中的长度至少为KKK的两个子序列,分别让它们的或值和与值最大。
思路
或值就是全部或起来,因为或起来只会变大不会变小。
与值就是选取其中的KKK个,因为与只会变小不会变大,我们就可以维护一个滑动的东西,每次把前面的减去后面的加上再统计一下最大值就好了。
代码
#include<cstdio>
#include<algorithm>
using namespace std;
int N, K, ans1, ans2;
int a[1000001], v[32];
int main() {
scanf("%d %d", &N, &K);
for (int i = 1; i <= N; i++) {
scanf("%d", &a[i]);
ans1 |= a[i];
for (int j = 0; j <= 32; j++)
v[j] += (a[i] >> j) & 1;//v[j]代表当前k个二进制第j位为1的数量
if (i >= K) {
for (int j = 0; j <= 32; j++)
v[j] -= (a[i - K] >> j) & 1;//滑
int s = 0;
for(int j = 0; j < 32; j++)
s += (v[j] == K) * (1 << j);
ans2 = max(ans2, s);
}
}
printf("%d %d", ans1, ans2);
}