有这样一类问题,插入、删除、整体查询。
为了避免删除操作,一般记录每个点的进入时间和删除时间,在线段树里每个节点开一个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; }