description:

一个长为n的序列 查询m次 每次输出最短区间长度 使得区间内异或和大等于x

solution:

区间长度只有3000,没有更新操作,支持离线。
先前缀异或和,而后先n*n 打表构造区间长度和获取区间值,区间值肯定取尽量大。
对数组求max操作后,明显具有单调性,二分答案即可

打表复杂度n*n 每次查询为logn

code:

#include <bits/stdc++.h>

using namespace std;

#define LL long long

const int N = 3005;

LL a[N],sum[N],res[N];

int main(){
    int n , m;
    cin >> n >> m;

    for(int i = 1;i <= n;i ++){
        scanf("%lld",&a[i]);
        sum[i] = sum[i - 1] ^ a[i];
    }

    for(int i = 0;i <= n;i ++){
        for(int j = i + 1;j <= n;j ++){
            res[j - i] = max(sum[j] ^ sum[i],res[j - i]);
        }
    }

    for(int i = 2;i < N;i ++){
        res[i] = max(res[i],res[i - 1]);
    }

    while(m --){
        int x;cin >> x;
        int pos = lower_bound(res + 1,res + 1 + N,x) - res;
        if(pos > n){
            cout << -1;
        }else{
            cout << pos;
        }
        cout << '\n';
    }
    return 0;
}