先考虑和最大,从高位到低位,如果这一位异或和为
1
,和一定是
再考虑
X1
最小。跟上面类似,如果异或和是
1
的话,尽量让
关键是如何维护这些限制条件。可以用
#include<cstdio>
#include<algorithm>
#include<bitset>
#include<iostream>
#include<vector>
using namespace std;
#define LL long long
const int maxn=100010,maxb=60;
bitset<maxn> f,g[maxb+10];
LL a[maxn],s;
int n,tot,p[maxb+10],ans[maxn];
int main()
{
int u;
scanf("%d",&n);
for (int i=0;i<n;i++) scanf("%I64d",&a[i]),s^=a[i];
for (int i=maxb;i>=0;i--)
if (!((s>>i)&1))
{
f.reset();
for (int j=0;j<n;j++)
if ((a[j]>>i)&1) f[j]=1;
f[n]=1;
for (int j=1;j<=tot;j++)
if (f[p[j]]) f^=g[j];
/*for (int j=n-1;j>=0;j--) cout<<f[j];
putchar('\n');*/
u=-1;
for (int j=0;j<n&&u==-1;j++)
if (f[j]) u=j;
if (u==-1) continue;
for (int j=1;j<=tot;j++)
if (g[j][u]) g[j]^=f;
tot++;
p[tot]=u;
g[tot]=f;
}
for (int i=maxb;i>=0;i--)
if ((s>>i)&1)
{
f.reset();
for (int j=0;j<n;j++)
if ((a[j]>>i)&1) f[j]=1;
f[n]=0;
for (int j=1;j<=tot;j++)
if (f[p[j]]) f^=g[j];
/*for (int j=n-1;j>=0;j--) cout<<f[j];
putchar('\n');*/
u=-1;
for (int j=0;j<n&&u==-1;j++)
if (f[j]) u=j;
if (u==-1) continue;
for (int j=1;j<=tot;j++)
if (g[j][u]) g[j]^=f;
tot++;
p[tot]=u;
g[tot]=f;
}
for (int i=1;i<=tot;i++) ans[p[i]]=g[i][n];
for (int i=0;i<n;i++)
printf("%d ",2-ans[i]);
}