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 }

 

posted @ 2021-02-16 19:13  古比  阅读(140)  评论(0编辑  收藏  举报