定义函数:
f
(
x
,
y
)
=
(
x
∣
y
)
−
y
f(x,y)=(x|y)-y
f(x,y)=(x∣y)−y
给出数组
a
a
a,要求求出使得
f
(
f
(
…
f
(
f
(
a
1
,
a
2
)
,
a
3
)
,
…
a
n
−
1
)
,
a
n
)
f(f(…f(f(a_1,a_2),a_3),…a_{n−1}),a_n)
f(f(…f(f(a1,a2),a3),…an−1),an)的值最大d的数组
a
a
a 的排列。
仔细观察函数定义,可以发现函数
f
(
x
,
y
)
=
x
&
(
∼
y
)
f(x,y)=x\&(∼y)
f(x,y)=x&(∼y)
所以最终结果为最终序列的第一个数和其他所有数的取反后的
&
\&
& 值,并且其他数的位置不重要。可以预处理出前缀和后缀,然后枚举第一个数即可,确定最大值对应的数。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5;
ll a[N],pre[N],suf[N];
int main()
{
int n,p,cnt=0;
ll maxn=-1;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
if(i==1)//注意
pre[1]=~a[i];
else
pre[i]=pre[i-1]&(~a[i]);
}
for(int i=n;i>=1;i--)
{
if(i==n)
suf[i]=~a[i];
else
suf[i]=suf[i+1]&(~a[i]);
}
for(int i=1;i<=n;i++)
{
ll res;
if(i==1)
res=a[i]&suf[i+1];
else if(i==n)
res=a[i]&pre[i-1];
else
res=(a[i]&pre[i-1]&suf[i+1]);
if(res>maxn)
{
maxn=res;
p=i;
}
}
printf("%lld%c",a[p],n==1?'\n':' ');
for(int i=1;i<=n;i++)
{
if(i!=p)
{
cnt++;
printf("%lld%c",a[i],cnt==n-1?'\n':' ');
}
}
return 0;
}