E. Iva & Pav

纯粹的發表於2024-06-29

原題連結

題解

已知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;
}