前几天的帖子:https://www.luogu.com.cn/discuss/649424
这里我给出一种比较简单的解法:
a | b ,结果只可能更大不可能更小
a ^ b 越大,则a | b 越大
所以这个问题就变成了求与每个数异或起来最大的数,然后用每个数去或上与他异或起来最大的数再取一个最大值就是答案。这一步我们可以用Trie解决,具体的请看代码:
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 100010;
int n , ans;
int a[N];
int son[N << 4][2] , idx;
void insert(int x){
int root = 0;
for(int i = 15;~i;i--){
int u = x >> i & 1;
if(!son[root][u]) son[root][u] = ++idx;
root = son[root][u];
}
}
int query(int x){
int root = 0;
int ans = 0;
for(int i = 15;~i;i--){
int u = x >> i & 1;
int k = u ^ 1;
if(son[root][k]){
if(k == 1) ans += (1 << i);
root = son[root][k];
}
else{
if(u == 1) ans += (1 << i);
root = son[root][u];
}
}
return ans;
}
int main(){
cin >> n;
for(int i = 1;i <= n;i++) scanf("%d" , &a[i]);
for(int i = 1;i <= n;i++) insert(a[i]);
for(int i = 1;i <= n;i++) ans = max(ans , (a[i] | query(a[i])));
cout << ans << endl;
return 0;
}
时间复杂度:
插入 O(16n)
查询 O(16n)
总的复杂度为 O(n)
空间复杂度: O(16n)