链接:http://acm.hdu.edu.cn/showproblem.php?pid=6579
题意:首先t组样例,每组样例先给出n和m,下一行给出n个数(a[i])。接下个m个操作,操作分为两种。lastans初始值为0。
0:给出l、r,l=(l^lastans)%n+1,r=(r^lastans)%n+1。if(l>r) swap(l,r)。输出[l,r]中某些数异或和的最大值。
1:给出x,a[++n]=x^lastans;
思路:区间异或和最大值,用线性基,和CF-1100F(链接:https://blog.csdn.net/birdmanqin/article/details/96965800)一样,加了些限制条件。
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 5e5+10;
int base[N][30],pos[N][30];
int n,m;
inline int Read()
{
int x=0,f=1; char ch=getchar();
while (ch<'0'||ch>'9') {if (ch=='-') f=-f; ch=getchar();}
while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return x*f;
}
char s[30];
inline void writeln(int x)
{
if (x<0) putchar('-'),x=-x;
if (!x) putchar('0'); else
{
int len=0;
while (x) s[++len]=x%10+'0',x/=10;
while (len) putchar(s[len--]);
}
putchar('\n');
}
inline void insert(int in,int x)
{
int temp,k=in;
for(int i=29;i>=0;i--) base[in][i]=base[in-1][i],pos[in][i]=pos[in-1][i];
for(int i=29;i>=0;i--)
{
if(x>>i)
{
if(!base[in][i])
{
base[in][i]=x;
pos[in][i]=k;
break;
}
else
{
if(k>pos[in][i])
{
//temp=k,k=pos[in][i],pos[in][i]=temp;
//temp=x,x=base[in][i],base[in][i]=temp;
swap(x,base[in][i]);
swap(k,pos[in][i]);
}
x^=base[in][i];
}
}
}
return ;
}
inline int query(int l,int r)
{
int ans=0;
for(int i=29;i>=0;i--)
if(pos[r][i]>=l&&(ans^base[r][i])>ans)
ans=(ans^base[r][i]);
return ans;
}
int main(void)
{
int t,op,l,r,x,last;
//scanf("%d",&t);
t=Read();
while(t--)
{
last=0;
n=Read();
m=Read();
//scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
//scanf("%d",&x);
x=Read();
insert(i,x);
}
for(int i=1;i<=m;i++)
{
//scanf("%d",&op);
op=Read();
if(op)
{
//scanf("%d",&x);
x=Read();
x=(x^last);
insert(++n,x);
}
else
{
//scanf("%d%d",&l,&r);
l=Read();
r=Read();
l=(l^last)%n+1;
r=(r^last)%n+1;
//cout<<l<<" "<<r<<" "<<n<<endl;
if(l>r) swap(l,r);
last=query(l,r);
writeln(last);
//printf("%d\n",last);
}
}
}
return 0;
}