題意:操作1問區間[l,r]異或和最大,操作2讓末尾添加一個數x
l = (l^las)%n+1. r = (r^las)%n+1. if(l>r)swap(l,r); x = x^las 。
其中las是上一次操作1的答案,初始爲0.
解:讓[ 1,i ]區間每個基底儘量靠近 i 這個位置和這個位置的值。
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 1e6+4;
int n,m,t;
int tp,las = 0;
int base[maxn][33],pos[maxn][33],bs[33],ps[33];
void add(int x,int id){
for(int i=30;i>=0;i--){
if(x&(1ll<<i)){
if(!bs[i]){
bs[i] = x;
ps[i] = id;
break;
}
if(ps[i]<id){
swap(bs[i],x);
swap(ps[i],id);
}
x^=bs[i];
}
}
}
int main()
{
scanf("%d",&t);
while(t--){
scanf("%d %d",&n,&m);
for(int i=0;i<=30;i++)bs[i] = 0,ps[i] = 0;
for(int i=1;i<=n;i++){
scanf("%d",&tp);
add(tp,i);
for(int j=30;j>=0;j--)base[i][j] = bs[j],pos[i][j] = ps[j];
}
las = 0;
int l,r,op,x;
while(m--){
scanf("%d",&op);
if(op==1){
scanf("%d",&x);
x^=las; n++;
add(x,n);
for(int j=30;j>=0;j--)base[n][j] = bs[j],pos[n][j] = ps[j];
}else{
scanf("%d %d",&l,&r);
l=(l^las)%n+1; r=(r^las)%n+1;
if(l>r)swap(l,r);
las = 0;
for(int j=30;j>=0;j--){
if(pos[r][j]>=l&&(las^base[r][j])>las){
las^=base[r][j];
}
}
printf("%d\n",las);
}
}
}
return 0;
}