定义函数: f(x,y)=(x∣y)−y
给出数组 a,要求求出使得 f(f(…f(f(a1,a2),a3),…an−1),an)的值最大d的数组 a 的排列。
仔细观察函数定义,可以发现函数 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;
}