设前缀疑惑和为
si
那么对于每个前缀
si
,相当于找一个
sj
使得
sj+(si⊕sj)
最大
从高位往低位贪心,判断是否存在。
可以用
O(nlogn)
的高维前缀和预处理
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N=300010;
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;
for(;c>'9'||c<'0';c=nc());for(;c>='0'&&c<='9';x=x*10+c-'0',c=nc());
}
int n,a[N],f[3000010];
int main(){
read(n);
memset(f,0x7f,sizeof(f)); f[0]=0;
for(int i=1;i<=n;i++)
read(a[i]),a[i]^=a[i-1],f[a[i]]=min(f[a[i]],i);
for(int k=0;k<=20;k++)
for(int i=1;i<=2000000;i++)
if(!(i>>k&1)) f[i]=min(f[i],f[i|(1<<k)]);
for(int i=1;i<=n;i++){
int cur=0;
for(int j=20;~j;j--)
if(!(a[i]>>j&1) && f[cur|(1<<j)]<=i) cur|=1<<j;
printf("%d\n",cur+(cur^a[i]));
}
return 0;
}