题名:
Cat, Fox and the Lonely Array
题意:
给定一个数组a,求出最小的k,满足数组每个长度为k的连续子数组元素按位或答案都相等。
题解:
可以想象成一个长度为k滑动窗口,每次向后移动移动一个位置,只需要保证当前窗口的首元素,与向后滑动一个位置新添加的元素对相或贡献一致即可,因为两个数相或有一个为一,答案就为一。
代码:
#include <iostream>
#include <vector>
using namespace std;
const int MAXN = 1e5 + 6;
int t, n;
int a[MAXN];
bool check(int mid)
{
vector<int> arr(22, 0);
for(int i=1;i<=mid;i++){
for(int j=0;j<=20;j++){
if ((a[i]>>j)&1){
arr[j+1]++;
}
}
}
for(int i=1;i+mid<=n;i++){
for (int j=0;j<=20;j++){
if ((a[i]>>j)&1) {
arr[j+1]--;
if(arr[j+1]==0){
arr[j+1]=-1;
}
}
}
for (int j=0;j<=20;j++){
if ((a[i + mid]>>j)&1){
if (arr[j+1]>0){
arr[j+1]++;
}
else if(arr[j+1]==-1) {
arr[j+1]=1;
}
else if(arr[j+1]==0) {
return false;
}
}
else {
if(arr[j+1]==-1) {
return false;
}
}
}
}
return true;
}
int main()
{
cin>>t;
while(t--) {
cin >> n;
for (int i=1;i<=n;i++) {
cin>>a[i];
}
int l=1,r=n,ans=0;
while(l<=r){
int mid=(l + r)>>1;
if(check(mid)){
r=mid-1;
ans= mid;
}
else{
l=mid+1;
}
}
cout<<ans<<endl;
}
return 0;
}