定义函数: f ( x , y ) = ( x y ) y f(x,y)=(x|y)-y f(x,y)=(xy)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),an1),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;
}