关于前几天的那个问题的解法
  • 板块灌水区
  • 楼主Fwio_
  • 当前回复25
  • 已保存回复25
  • 发布时间2023/8/6 08:46
  • 上次更新2023/11/3 05:38:39
查看原帖
关于前几天的那个问题的解法
965238
Fwio_楼主2023/8/6 08:46

前几天的帖子:https://www.luogu.com.cn/discuss/649424


这里我给出一种比较简单的解法:

  1. aa | bb ,结果只可能更大不可能更小

  2. aa ^ bb 越大,则aa | bb 越大

所以这个问题就变成了求与每个数异或起来最大的数,然后用每个数去或上与他异或起来最大的数再取一个最大值就是答案。这一步我们可以用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(16n)O(16n)

总的复杂度为 O(n)O(n)

空间复杂度: O(16n)O(16n)

2023/8/6 08:46
加载中...