题意
给定一个 位的数组 ,并将 分开成 个连续的部分,并使得 ,并输出 的最大值。
思路
本题目主要考察与运算。
首先设 为 , 为 。根据题目,,且 ,所以 。因为 ,所以 。所以如果数组 能满足题意的分成几个连续的部分,。所以如果数组的 ,输出 1 即可。
然后,我们设 ,我们遍历数组,依次寻找能使 的最小的 。如果找得到,就意味着剩下的数组还能继续分割,所以 。因为计算 耗时很大,我们需要预处理。
代码
#include<bits/stdc++.h>
using namespace std;
int t,n,a[200005];
int ask[200005];
inline int find(int x) {
int anss = a[x];
if(anss == 0) return x;
x++;
for(;x <= n;x++) {
anss &= a[x];
if(anss == 0) return x;
}
return -114514;
}
signed main() {
scanf("%d",&t);
while(t--) {
scanf("%d",&n);
for(int i = 1;i <= n;i++) scanf("%d",&a[i]);
memset(ask,0,sizeof(ask));
ask[n] = a[n];//预处理
for(int i = n - 1;i >= 1;i--) ask[i] = ask[i + 1] & a[i];
int ans = ask[1],ans1 = 1;
if(ans) {
printf("1\n");
continue;
}
for(int i = 1;i <= n;) {
int x = find(i);
if(x < i or x == n or ask[x + 1] != ans) {
printf("%d\n",ans1);
break;
}
ans1++;
i = x + 1;
}
}
}