http://acm.hdu.edu.cn/showproblem.php?pid=6579
线性基https://blog.csdn.net/a_forever_dream/article/details/83654397
模板https://blog.csdn.net/u013534123/article/details/79875825
我们考虑在每个位置求出首位置到当前位置的线性基。同时我们要使线性基中高位的位置所选的数尽量靠后。这样我们维护线性基的时候在同时维护一个位置信息就好了。
#include<cstring> #include<algorithm> #include<vector> #include<map> #include<queue> #include<cstdio> #include<stack> #include<cmath> #include<iostream> #define ll long long #define lowbit(x) x&(-x) #define maxn 1050000 #define inf 0x3f3f3f3f using namespace std; int a[maxn][35]; //存线性基 int b[maxn][35]; //存位置 int k; void add(int x) { int cur=++k; for(int i=31;i>=0;i--) { a[k][i]=a[k-1][i]; b[k][i]=b[k-1][i]; } for(int i=31;i>=0;i--) { if(x>>i) { if(!a[k][i]) { a[k][i]=x; b[k][i]=cur; break; } else { if(cur>b[k][i]) { swap(a[k][i],x); swap(b[k][i],cur); } x^=a[k][i]; } } } } int query(int l,int r) { l=l%k+1; r=r%k+1; if(l>r) swap(l,r); int ret=0; for(int i=31;i>=0;i--) { if(b[r][i]>=l) { ret=max(ret,a[r][i]^ret); } } return ret; } int main() { int t; scanf("%d",&t); int n,m; while(t--) { k=0; scanf("%d%d",&n,&m); int x; for(int i=0;i<n;i++) { scanf("%d",&x); add(x); } int op,y,ans=0; while(m--) { scanf("%d %d",&op,&x); if(op==0) { scanf("%d",&y); ans=query(x^ans,y^ans); printf("%d ",ans); } else { add(x^ans); } } } }