I 区间异或
思路:题目给出的数组范围只有3e3,我们计算出每一种长度的最大异或值
然后根据贪心思想,如果长度为3的异或值小于长度为2的异或值,那我们宁可长度为2即可
即:长度为3的异或值=max(长度为小于等于3的异或值)
我们用一个ans数组来表示,长度1~n的异或值
可想而知这是一个不递减序列
然后我们二分即可
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int maxn=3e3+10; 5 ll a[maxn]; 6 ll dp[maxn][maxn]; 7 ll ans[maxn]; 8 int main() 9 { 10 int n,k; 11 scanf("%d%d",&n,&k); 12 for(int i=1;i<=n;i++){ 13 scanf("%lld",&a[i]); 14 dp[i][i]=a[i]; 15 ans[1]=max(ans[1],a[i]); 16 } 17 for(int len=2;len<=n;len++){ 18 for(int i=1;i<=n;i++){ 19 int j=i+len-1; 20 if(j>n) continue; 21 dp[i][j]=dp[i][j-1]^a[j]; 22 ans[j-i+1]=max(ans[j-i+1],dp[i][j]); 23 } 24 } 25 for(int i=2;i<=n;i++){ 26 if(ans[i]<ans[i-1]) ans[i]=ans[i-1]; 27 } 28 while(k--){ 29 int tmp; 30 scanf("%d",&tmp); 31 int l=1,r=n; 32 int res; 33 while(l<=r){ 34 int mid=l+r>>1; 35 if(ans[mid]>=tmp){ 36 res=mid; 37 r=mid-1; 38 } 39 else{ 40 l=mid+1; 41 } 42 } 43 printf("%d\n",res); 44 } 45 return 0; 46 }