明显的分支线段树加线性基
我刚开始每个节点都开了个线性基,内存是满的
O(nlogm)
O
(
n
log
m
)
,被卡了
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>
#include <cstring>
using namespace std;
const int N=500010;
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline void read(int &x){
char c=nc(); x=0; int f=1;
for(;c>'9'||c<'0';c=nc())if(c=='-') f=-f;
for(;c>='0'&&c<='9';x=x*10+c-'0',c=nc()); x*=f;
}
int n,a[N],b[N],cnt[N],bg[N];
struct lbase{
int a[35];
lbase(){ memset(a,0,sizeof(a)); }
void Add(int x){
for(int i=31;~i;i--){
if(!((x>>i)&1)) continue;
if(!a[i]){
a[i]=x; break;
}
x^=a[i];
}
}
friend lbase operator +(lbase a,lbase b){
for(int i=0;i<=31;i++){
int x=b.a[i];
if(!x) continue;
for(int j=i;~j;j--){
if(!((x>>j)&1)) continue;
if(!a.a[j]){
a.a[j]=x; break;
}
x^=a.a[j];
}
}
return a;
}
int Max(){
int ret=0;
for(int i=31;~i;i--){
if(ret>>i&1) continue;
ret^=a[i];
}
return ret;
}
};
void PutAns(int x){
if(x>=10) PutAns(x/10); putchar(x%10+'0');
}
vector<int> opt[N<<2];
int ans[N];
void Add(int g,int l,int r,int L,int R,int x){
if(l==L && r==R) return opt[g].push_back(x);
int mid=L+R>>1;
if(r<=mid) Add(g<<1,l,r,L,mid,x);
else if(l>mid) Add(g<<1|1,l,r,mid+1,R,x);
else Add(g<<1,l,mid,L,mid,x),Add(g<<1|1,mid+1,r,mid+1,R,x);
}
void Query(int g,int l,int r,lbase a){
for(vector<int>::iterator it=opt[g].begin();it!=opt[g].end();it++) a.Add(*it);
if(l==r) return ans[l]=a.Max(),void();
int mid=l+r>>1;
Query(g<<1,l,mid,a); Query(g<<1|1,mid+1,r,a);
}
int main(){
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
read(n);
for(int i=1;i<=n;i++)
read(a[i]),b[i]=a[i]<0?-a[i]:a[i];
int t=n;
sort(b+1,b+1+t); t=unique(b+1,b+1+t)-b-1;
for(int i=1;i<=n;i++){
if(a[i]>0)
a[i]=lower_bound(b+1,b+1+t,a[i])-b;
else
a[i]=-(lower_bound(b+1,b+1+t,-a[i])-b);
}
for(int i=1;i<=n;i++){
if(a[i]>0){
if(!cnt[a[i]]) bg[a[i]]=i;
cnt[a[i]]++;
}
else{
cnt[-a[i]]--;
if(!cnt[-a[i]]) Add(1,bg[-a[i]],i-1,1,n,b[-a[i]]);
}
}
for(int i=1;i<=t;i++)
if(cnt[i]) Add(1,bg[i],n,1,n,b[i]);
Query(1,1,n,lbase());
for(int i=1;i<=n;i++)
PutAns(ans[i]),putchar('\n');
return 0;
}