【tmp】线段树按时间分治
其实就是把每个价值往存在的时间区间里面丢,线段树上每个节点存这个节点代表的区间有哪些值,注意是存在最大的完全包含区间内
(也有线性基啦qwq)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int MAXN=5*(1e5)+1,TOP=30,SEG=MAXN*2;
int ed[MAXN],st[MAXN];
int a[MAXN],b[MAXN],id[MAXN];
int ans[MAXN],cnt[MAXN];
int n,m;
struct xxj{/*{{{*/
int a[TOP+1];
void init(){memset(a,0,sizeof(a));}
bool insert(int x){
for (int i=TOP;i>=0;--i){
if (x&(1<<i)){
if (!a[i]){
a[i]=x;
break;
}
x^=a[i];
}
}
return x>0;
}
int query_max(){
int ret=0;
for (int i=TOP;i>=0;--i)
if ((ret^a[i])>ret) ret^=a[i];
return ret;
}
void merge(xxj x){
for (int i=TOP;i>=0;--i)
if (x.a[i])
insert(x.a[i]);
}
};/*}}}*/
namespace Seg{/*{{{*/
int ch[SEG][2];
int tot,n;
vector<int> rec[SEG];
void _build(int x,int l,int r){
if (l==r) return;
int mid=l+r>>1;
ch[x][0]=++tot; _build(ch[x][0],l,mid);
ch[x][1]=++tot; _build(ch[x][1],mid+1,r);
}
void build(int _n){n=_n; tot=1; _build(1,1,n);}
void _update(int x,int l,int r,int lx,int rx,int delta){
if (l<=lx&&rx<=r){
rec[x].push_back(delta);
return;
}
int mid=lx+rx>>1;
if (l>mid) _update(ch[x][1],l,r,mid+1,rx,delta);
else if (r<=mid) _update(ch[x][0],l,r,lx,mid,delta);
else{
_update(ch[x][0],l,mid,lx,mid,delta);
_update(ch[x][1],mid+1,r,mid+1,rx,delta);
}
}
void update(int l,int r,int delta){_update(1,l,r,1,n,delta);}
void _query(int x,int lx,int rx,xxj now){
for (int i=0;i<rec[x].size();++i)
now.insert(rec[x][i]);
if (lx==rx){
ans[lx]=now.query_max();
return;
}
int mid=lx+rx>>1;
_query(ch[x][0],lx,mid,now);
_query(ch[x][1],mid+1,rx,now);
}
void solve(){xxj now; now.init();_query(1,1,n,now);}
}/*}}}*/
void prework();
int Abs(int x){return x<0?-x:x;}
int main(){
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
#endif
int x;
scanf("%d",&n);
for (int i=1;i<=n;++i) scanf("%d",a+i),b[i]=Abs(a[i]);
prework();
Seg::build(n);
for (int i=1;i<=n;++i)
if (a[i]>0){
++cnt[id[i]];
if (cnt[id[i]]==1)
st[id[i]]=i;
}
else{
--cnt[id[i]];
if (cnt[id[i]]==0){
Seg::update(st[id[i]],i-1,-a[i]);
st[id[i]]=0;
}
}
for (int i=1;i<=n;++i)
if (st[id[i]])
Seg::update(st[id[i]],n,Abs(a[i])),st[id[i]]=0;
Seg::solve();
for (int i=1;i<=n;++i)
printf("%d\n",ans[i]);
}
void prework(){
sort(b+1,b+1+n);
unique(b+1,b+1+n);
for (int i=1;i<=n;++i){
id[i]=Abs(a[i]);
id[i]=lower_bound(b+1,b+1+n,id[i])-b;
}
}