E. Iva & Pav
题解
已知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;
}

浙公网安备 33010602011771号