bzoj4184

时间:2022-12-02 06:15:39

题解:

按时间分治线段树

然后线性基维护一下就好了

尝试了一下循环展开并没有什么效果

代码:

#include <bits/stdc++.h>
using namespace std;
const int N=5e5+;
const int mo=N*;
int n,m,ph[N*],pt[N*],f[N*],g[N*],ans2[N];
int dy[][];
vector<int> ve[N*];
#define rint register int
#define IL inline
char ss[<<],*A=ss,*B=ss;
IL char gc(){return A==B&&(B=(A=ss)+fread(ss,,<<,stdin),A==B)?EOF:*A++;}
template<class T> void read(T&x){
rint f=,c;
while (c=gc(),c<||<c)
if (c=='-') f=-;
x=c^;
while (c=gc(),<c&&c<) x=(x<<)+(x<<)+(c^);
x*=f;
}
IL void insert(int x,int y)
{
int xx=x%mo;
while (f[xx]) xx++;
f[xx]=x; g[xx]=y;
}
IL int find(int x)
{
int xx=x%mo;
while (f[xx]!=x) xx++;
return(xx);
}
#define mid ((ph[x]+pt[x])/2)
void build(int x,int h,int t)
{
ph[x]=h; pt[x]=t;
if (h==t) return;
build(x*,h,mid); build(x*+,mid+,t);
}
void insert2(int x,int h,int t,int k)
{
if (h<=ph[x]&&pt[x]<=t)
{
ve[x].push_back(k);
return;
}
if (h<=mid) insert2(x*,h,t,k);
if (mid<t) insert2(x*+,h,t,k);
}
void dfs(int x,int cnt)
{
for (rint i=;i<=;i++) dy[cnt][i]=dy[cnt-][i];
rint len=ve[x].size();
for (rint i=;i<=len/;i++)
{ if (i*>=len) break;
rint y1=ve[x][i*],y2=ve[x][i*+],
y3=ve[x][i*+],y4=ve[x][i*+];
for (rint i1=;i1>=;i1--)
if (y1&(<<i1))
if (!dy[cnt][i1])
{
dy[cnt][i1]=y1; break;
} else y1^=dy[cnt][i1]; if (i*+>=len) break;
for (rint i2=;i2>=;i2--)
if (y2&(<<i2))
if (!dy[cnt][i2])
{
dy[cnt][i2]=y2; break;
} else y2^=dy[cnt][i2]; if (i*+>=len) break;
for (rint i3=;i3>=;i3--)
if (y3&(<<i3))
if (!dy[cnt][i3])
{
dy[cnt][i3]=y3; break;
} else y3^=dy[cnt][i3]; if (i*+>=len) break;
for (rint i4=;i4>=;i4--)
if (y4&(<<i4))
if (!dy[cnt][i4])
{
dy[cnt][i4]=y4; break;
} else y4^=dy[cnt][i4];
}
if (ph[x]==pt[x])
{
rint ans=;
for (rint i=;i>=;i--)
if (dy[cnt][i]&&!(ans&(<<i))) ans^=dy[cnt][i];
ans2[ph[x]]=ans;
return;
}
dfs(x*,cnt+);
dfs(x*+,cnt+);
}
int main()
{
freopen("4184.in","r",stdin);
freopen("4184.out","w",stdout);
read(n);
build(,,n);
for (int i=;i<=n;i++)
{
int x;
read(x);
if (x<)
{
int y=find(-x);
insert2(,g[y],i-,-x);
f[y]=; g[y]=;
} else
{
insert(x,i);
}
}
for (rint i=;i<=N*-;i++)
if (f[i])
{
insert2(,g[i],n,f[i]);
}
dfs(,);
for (int i=;i<=n;i++)
printf("%d\n",ans2[i]);
return ;
}

相关文章