有这样一类问题,插入、删除、整体查询。
为了避免删除操作,一般记录每个点的进入时间和删除时间,在线段树里每个节点开一个vector,然后这个区间里插入这个数,最后dfs一遍就只有插入操作,没有删除操作了。
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<vector>
#include<set>
#define maxn 500010
using namespace std;
struct yts
{
int l,r;
vector<int> d;
}t[4*maxn];
struct yts1
{
int a[31];
int& operator[](int x)
{
return a[x];
}
}c;
int n,m;
int a[maxn];
set<pair<int,int> > p;
yts1 insert(yts1 c,int x)
{
for (int i=30;i>=0;i--)
if ((x>>i)&1)
{
if (!c[i])
{
c[i]=x;
break;
}
else x^=c[i];
}
return c;
}
void build(int i,int l,int r)
{
t[i].l=l;t[i].r=r;
if (l==r) return;
int mid=(l+r)/2;
build(i*2,l,mid);build(i*2+1,mid+1,r);
}
void insert(int i,int l,int r,int x)
{
if (l<=t[i].l && t[i].r<=r)
{
t[i].d.push_back(x);
return;
}
int mid=(t[i].l+t[i].r)/2;
if (l<=mid) insert(i*2,l,r,x);
if (mid<r) insert(i*2+1,l,r,x);
}
void dfs(int i,yts1 k)
{
for (int j=0;j<t[i].d.size();j++)
k=insert(k,t[i].d[j]);
if (t[i].l==t[i].r)
{
int now=0;
for (int i=30;i>=0;i--)
if ((now^k[i])>now) now^=k[i];
printf("%d\n",now);
return;
}
dfs(i*2,k);
dfs(i*2+1,k);
}
int main()
{
scanf("%d",&n);
build(1,1,n);
for (int i=1;i<=n;i++)
{
int x;
scanf("%d",&x);
if (x>0) p.insert(make_pair(x,i));
else
{
pair<int,int> q=*p.lower_bound(make_pair(abs(x),0));
insert(1,q.second,i-1,abs(x));
p.erase(q);
}
}
set<pair<int,int> >::iterator i;
for (i=p.begin();i!=p.end();i++) insert(1,(*i).second,n,(*i).first);
dfs(1,c);
return 0;
}