原題連結
題解
已知l,則r越大,f(l,r) 越小,因此具有單調性,我們可以在logn的時間裡找最佳r,可是如何在 \(O(1)\) 的時間裡計算f(l,r)?
由於與具有重疊不變性,所以我們可以預處理每 \(2^k\) 長度的區間,然後左端點所在的區間和右端點所在的區間與一下
code
#include<bits/stdc++.h>
using namespace std;
int k;
int st[25][200005];
int a[200005];
bool check(int l,int r)
{
int len=(r-l+1);
int lg=log2(len);
int ans=st[lg][l]&st[lg][r-(1<<lg)+1];
return ans>=k;
}
int main()
{
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
st[0][i]=a[i];
}
for(int i=1;(1<<i)<=n;i++)
{
for(int j=1;j+(1<<i)-1<=n;j++)
{
st[i][j]=st[i-1][j]&st[i-1][j+(1<<(i-1))];
}
}
int q;
cin>>q;
while(q--)
{
int l;
cin>>l>>k;
int x=l-1,y=n+1;
while(x+1<y)
{
int mid=(x+y)/2;
if(check(l,mid)) x=mid;
else y=mid;
}
if(x!=l-1) cout<<x<<" ";
else cout<<"-1 ";
}
cout<<'\n';
}
return 0;
}