# 【BZOJ4184】shallot（线段树分治，线性基）

## 题面

6
1 2 3 4 -2 -3

1
3
3
7
7
5

### HINT

N<=500000,Ai<=2^31-1

## 题解

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define ll long long
#define RG register
#define lson (now<<1)
#define rson (now<<1|1)
#define MAX 500500
{
RG int x=0,t=1;RG char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=-1,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*t;
}
int n,a[MAX],S[MAX],len,ans[MAX];
struct Number{int x,l,r;}p[MAX];
vector<int> seg[MAX<<2];
int nt[MAX],h[MAX],tot;
void Modify(int now,int l,int r,int L,int R,int x)
{
if(L<=l&&r<=R){seg[now].push_back(x);return;}
int mid=(l+r)>>1;
if(L<=mid)Modify(lson,l,mid,L,R,x);
if(R>mid)Modify(rson,mid+1,r,L,R,x);
}
struct xxj
{
int p[32],ele;
void insert(int x)
{
if(ele==32)return;
for(int i=31;~i;--i)
if(x&(1<<i))
{
if(!p[i]){p[i]=x;++ele;break;}
x^=p[i];
}
}
int Query(int x){for(int i=31;~i;--i)x=max(x,x^p[i]);return x;}
}G;
void Divide(int now,int l,int r,xxj G)
{
for(int i=seg[now].size()-1;(~i)&&G.ele<32;--i)G.insert(seg[now][i]);
for(int i=l;i<=r;++i)ans[i]=max(ans[i],G.Query(0));
if(l==r)return;int mid=(l+r)>>1;
Divide(lson,l,mid,G);Divide(rson,mid+1,r,G);
}
int main()
{
freopen("4184.in","r",stdin);
freopen("4184.out","w",stdout);
for(int i=1;i<=n;++i)S[i]=abs(a[i]);
sort(&S[1],&S[n+1]);len=unique(&S[1],&S[n+1])-S-1;
for(int i=1;i<=n;++i)
if(a[i]>0)
{
int x=lower_bound(&S[1],&S[len+1],a[i])-S;
nt[++tot]=h[x];h[x]=tot;
p[tot]=(Number){a[i],i,0};
}
else
{
int x=lower_bound(&S[1],&S[len+1],-a[i])-S;
int pos=h[x];p[pos].r=i-1;
h[x]=nt[pos];
}
for(int i=1;i<=tot;++i)if(!p[i].r)p[i].r=n;
for(int i=1;i<=tot;++i)Modify(1,1,n,p[i].l,p[i].r,p[i].x);
Divide(1,1,n,G);
for(int i=1;i<=n;++i)printf("%d\n",ans[i]);
return 0;
}


posted @ 2018-07-28 19:41  小蒟蒻yyb  阅读(493)  评论(1编辑  收藏  举报