版权声明:写得不好,转载请通知一声,还请注明出处,感激不尽 https://blog.csdn.net/As_A_Kid/article/details/85015180
Problem
Solution
转化一下
题目就转化为了对于每个
,求出一个最优的
我们思考一下对于一定的
,
要怎么样
最大
对二进制下的单独一位进行考虑,会发现式子的真值表是这样的
x\y | 0 | 1 |
---|---|---|
0 | 0 | 1 |
1 | 1 | 1 |
那么每一位都是独立的,从高到低贪心即可。那么我们就需要查询在是否存在一个
且
是前几位贪心结果的超集,用高维前缀和解决。
时间复杂度
Code
#include <cstring>
#include <cstdio>
#define rg register
using namespace std;
typedef long long ll;
const int maxn=300010,maxm=1100000;
template <typename Tp> inline int getmin(Tp &x,Tp y){return y<x?x=y,1:0;}
template <typename Tp> inline int getmax(Tp &x,Tp y){return y>x?x=y,1:0;}
template <typename Tp> inline void read(Tp &x)
{
x=0;int f=0;char ch=getchar();
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') f=1,ch=getchar();
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
if(f) x=-x;
}
int n,mx,l,N,ans,mi[25],a[maxn],f[maxm];
int main()
{
read(n);mi[0]=1;
for(int i=1;i<=20;i++) mi[i]=mi[i-1]<<1;
memset(f,0x3f,sizeof(f));
for(rg int i=1;i<=n;i++)
{
read(a[i]);a[i]^=a[i-1];
getmin(f[a[i]],i);getmax(mx,a[i]);
}
for(N=1;N<=mx;N<<=1) ++l;
for(int i=0;i<l;i++)
for(rg int j=0;j<N;j++)
if(!(j&mi[i]))
getmin(f[j],f[j|mi[i]]);
for(rg int i=1;i<=n;i++)
{
ans=0;
for(int j=l-1;~j;j--)
if(!(a[i]&mi[j])&&f[ans|mi[j]]<=i)
ans|=mi[j];
printf("%d\n",ans+(ans^a[i]));
}
return 0;
}