单纯放个代码,可能以后用的到…
实际上是写了个这玩意疯狂MLE
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
const int maxm=1e5+100;
int n,m,tot;
int val[maxm];
struct node{
int p[33];
inline void clear(){memset(p,0,sizeof(p));}
inline void insert(int x)
{
for(int i=31;i>=0;i--)
{
if(!p[i])
{
p[i]=x;
return;
}
x^=p[i];
}
}
inline int ask()
{
int res=0;
for(int i=31;i>=0;i--) res=std::max(res,res^p[i]);
}
};
struct tree{
node tag[maxm*2],ans;
inline void merge(node &x,node &y)
{
for(int i=31;i>=0;i--) if(x.p[i]) y.insert(x.p[i]);
}
inline void pushup(int o)
{
merge(tag[(o<<1)],tag[o]);
merge(tag[(o<<1)|1],tag[o]);
}
inline void clear(){memset(tag,0,sizeof(tag));}
void insert(int o,int l,int r,int ind,int x)
{
if(l>=r)
{
tag[o].clear();
tag[o].insert(x);
return;
}
int mid=(l+r)>>1;
ind<=mid?insert((o<<1),l,mid,ind,x):insert((o<<1)|1,mid+1,r,ind,x);
pushup(o);
}
void build(int o,int l,int r)
{
if(l>=r)
{
tag[o].insert(val[l]);
return;
}
int mid=(l+r)>>1;
build((o<<1),l,mid),build((o<<1)|1,mid+1,r);
pushup(o);
}
void ask(int o,int l,int r,int ql,int qr)
{
if((l<=ql)&&(r<=qr))
{
merge(tag[o],ans);
return;
}
int mid=(l+r)>>1;
if(ql<=mid) ask((o<<1),l,mid,ql,qr);
if(qr>mid) ask((o<<1)|1,mid+1,r,ql,qr);
}
}st;
inline void work()
{
st.clear();
scanf("%d%d",&n,&m);
int last=0;
int tot=n+m;
for(int i=1;i<=n;i++) scanf("%d",&val[i]);
st.build(1,1,tot);
for(int i=1;i<=m;i++)
{
int opt,l,r;
scanf("%d%d",&opt,&l);
if(opt==0)
{
scanf("%d",&r);
l=(l^last)%n+1;
r=(r^last)%n+1;
if(l>r) std::swap(l,r);
printf("%d %d\n",l,r);
st.ans.clear();
st.ask(1,1,tot,l,r);
last=st.ans.ask();
printf("%d\n",last);
}
else
{
val[++n]=l^last;
st.insert(1,1,tot,n,val[n]);
}
}
}
int main()
{
int t;
scanf("%d",&t);
for(int i=1;i<=t;i++) work();
return 0;
}