HDU6579 Operation
题目大意:
给定\(5e5\)的数列,和\(5e5\)个操作。操作有下面两种:
- 数列后面加入一个数x
- 给定区间[l,r],求出区间内随意挑出某些数的异或最大值
前缀线性基,只不过他要求在线。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=5e5+10;
int t,n,m;
int d[maxn<<1][32],pos[maxn<<1][32];
int cnt;
void insert(int x)
{
cnt++;
for(int i=31;i>=0;--i)
{
d[cnt][i]=d[cnt-1][i];
pos[cnt][i]=pos[cnt-1][i];
}
int cur=cnt;
for(int i=31;i>=0;--i)
{
if(x&(1ll<<i))
{
if(d[cnt][i])
{
if(pos[cnt][i]<cur)
{
swap(pos[cnt][i],cur);
swap(d[cnt][i],x);
}
x^=d[cnt][i];
}
else
{
d[cnt][i]=x;
pos[cnt][i]=cur;
break;
}
}
}
}
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
cnt=0;
memset(d,0,sizeof(d));
memset(pos,0,sizeof pos);
for(int x,i=1;i<=n;++i)
{
scanf("%d",&x);
insert(x);
}
int lastans=0;
for(int op,l,r,i=1;i<=m;++i)
{
scanf("%d",&op);
if(op==0)
{
scanf("%d%d",&l,&r);
l=(l^lastans)%cnt+1;
r=(r^lastans)%cnt+1;
if(l>r)swap(l,r);
lastans=0;
for(int i=31;i>=0;--i)
if(pos[r][i]>=l)lastans=max(lastans,lastans^d[r][i]);
printf("%d\n",lastans);
}
else
{
scanf("%d",&l);
insert(l^lastans);
}
}
}
return 0;
}