传送门

 

•参考资料

  [1]:在线线性基

  [2]:离线线性基

  [3]:离线线性基

•题意

  给你 n 个数,m 次询问;

  每次询问给定一个区间 $l,r$,求 $a_{l \cdots r}$ 异或的最大值;

•线段树+线性基

  参考了一下资料[1],学会了如何将线性基和线段树结合;

  虽然在此题中会 TLE,但是却学到了不少东西;

  首先,在建树的时候,将叶节点上的值插入到线性基中;

  在回溯的时候,通过 Merge 操作,将 pos 的儿子节点的线性基合并到 pos 的线性基上;

  类似于常规线段树中的 pushUp 操作;

  此算法可以用来做这道题:洛谷P4839

•Code(线段树TLE版本)

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define ls(x) (x<<1)
  4 #define rs(x) (x<<1|1)
  5 const int maxn=5e5+50;
  6  
  7 int n,q;
  8 int a[maxn];
  9 struct Seg
 10 {
 11     int l,r;
 12     int a[25];
 13     int mid(){return l+((r-l)>>1);}
 14     void Insert(int x)
 15     {
 16         for(int i=20;i >= 0;--i)
 17         {
 18             if(x&(1<<i))
 19             {
 20                 if(!a[i])
 21                 {
 22                     a[i]=x;
 23                     return ;
 24                 }
 25                 x ^= a[i];
 26             }
 27         }
 28     }
 29     int Max()
 30     {
 31         int ans=0;
 32         for(int i=20;i >= 0;--i)
 33             ans=max(ans,ans^a[i]);
 34         return ans;
 35     }
 36 }seg[maxn<<2];
 37  
 38 Seg Marge(Seg a,Seg b)
 39 {
 40     Seg tmp=b;
 41     for(int i=0;i <= 20;++i)
 42         if(a.a[i])
 43             tmp.Insert(a.a[i]);
 44     return tmp;
 45 }
 46 void buildSeg(int l,int r,int pos)
 47 {
 48     seg[pos].l=l;
 49     seg[pos].r=r;
 50  
 51     if(l == r)
 52     {
 53         seg[pos].Insert(a[l]);
 54         return ;
 55     }
 56  
 57     int mid=l+((r-l)>>1);
 58     buildSeg(l,mid,ls(pos));
 59     buildSeg(mid+1,r,rs(pos));
 60  
 61     seg[pos]=Marge(seg[ls(pos)],seg[rs(pos)]);
 62     seg[pos].l=l;///此处要注意,因为Marge返回的结果未给l,r赋值
 63     seg[pos].r=r;
 64 }
 65 Seg Query(int l,int r,int pos)
 66 {
 67     if(seg[pos].l == l && seg[pos].r == r)
 68         return seg[pos];
 69  
 70     int mid=seg[pos].mid();
 71  
 72     if(r <= mid)
 73         return Query(l,r,ls(pos));
 74     else if(l > mid)
 75         return Query(l,r,rs(pos));
 76     else
 77         return Marge(Query(l,mid,ls(pos)),Query(mid+1,r,rs(pos)));
 78 }
 79 void Solve()
 80 {
 81     for(int i=1;i <= q;++i)
 82     {
 83         int l,r;
 84         scanf("%d%d",&l,&r);
 85  
 86         Seg ans=Query(l,r,1);
 87  
 88         printf("%d\n",ans.Max());
 89     }
 90 }
 91 int main()
 92 {
 93 //    freopen("C:\\Users\\hyacinthLJP\\Desktop\\in&&out\\contest","r",stdin);
 94     scanf("%d",&n);
 95     for(int i=1;i <= n;++i)
 96         scanf("%d",a+i);
 97     buildSeg(1,n,1);
 98  
 99     scanf("%d",&q);
100     Solve();
101  
102     return 0;
103 }
View Code

相关文章:

  • 2022-12-23
  • 2022-01-07
  • 2022-01-07
  • 2022-01-07
  • 2021-05-06
  • 2021-04-10
  • 2021-08-11
猜你喜欢
  • 2021-06-09
  • 2022-01-07
  • 2021-12-31
  • 2021-11-21
  • 2021-11-18
  • 2021-06-26
  • 2021-08-13
相关资源
相似解决方案