链接
https://codeforces.com/contest/1300/problem/C
题意
f ( x , y ) = ( x ∣ y ) − y f(x,y)=(x\mid 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) 的最大值
思路
易得 f ( x , y ) = ( x ∣ y ) − y = x & ( ∼ y ) f(x,y)=(x\mid y)-y=x\&(\sim y) f(x,y)=(x∣y)−y=x&(∼y)
可以发现对于二进制下的每一位,当 x x x 为 1 1 1, y y y 为 0 0 0 时,才对答案有贡献
所以可以预处理 p r e f i x [ 1 ∼ x ] prefix[1 \sim x] prefix[1∼x] 和 s u f f i x [ x ∼ n ] suffix[x \sim n] suffix[x∼n] 的或运算和
然后枚举 1 ∼ n 1 \sim n 1∼n 作为第一个数:求出 a [ i ] & ∼ ( p r e f i x [ 1 ∼ x ] ∣ s u f f i x [ x ∼ n ] ) a[i] \& \sim (prefix[1 \sim x]|suffix[x \sim n]) a[i]&∼(prefix[1∼x]∣suffix[x∼n]) 的最大值
代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,a[N],pre[N],suf[N];
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++) pre[i]=pre[i-1]|a[i];
for(int i=n;i;i--) suf[i]=suf[i+1]|a[i];
int res=0;
int x=1;
for(int i=1;i<=n;i++)
if((a[i]&~(pre[i-1]|suf[i+1]))>res) {
res=a[i]&~(pre[i-1]|suf[i+1]);
x=i;
}
cout<<a[x]<<" ";
for(int i=1;i<=n;i++) if(i!=x) cout<<a[i]<<" ";
cout<<endl;
return 0;
}