異或最大值


1216: 異或最大值#

http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1216

Time Limit: 2 Sec Memory Limit: 128 Mb

Description###

給定一些數,求這些數中兩個數的異或值最大的那個值

Input###

多組數據。第一行為數字個數n,1 <= n <= 10 ^ 5。接下來n行每行一個32位有符號非負整數。

Output###

任意兩數最大異或值

Sample Input###

3
3
7
9

Sample Output###

14

Hint###

Source
CSGrandeur的數據結構習題

思路:

暴力\(N^2\)鐵定超時

貪心一下

xor 即不同為1,相同為0

如果一個數a去找能得到 最大異或值 的b

(我也搞不清楚哪里是最高位了,就把最右邊當第一位吧)

二進制較高位不同的數字一定比他們二進制較高位相同的異或值大

比如 有三個數 10 6 8

10的二進制是1010

6的二進制是0101

8的二進制是1000

則和10異或值最大的就是6(第4位比較)

貪心好了

下面就該實現了

二進制無非就0和1

要快速查找,就可以建一個01字典樹

比如這樣

cmd-markdown-logo

當范圍大到int也最多有30層 時間復雜度\(nlogn\)

ps:與(&)和或(|)的最大值也是可以求的,博客.

考試居然忘了輸出\n了,我TM真的是,╮(╯▽╰)╭ 哎

實現的話,sturct記錄左孩子(1)右孩子(0)的位置

從大到小一層層遍歷就好了,實現也沒辣么難

附上又臭又長的代碼

/*
                       ▍ ★∴
  ....▍▍....█▍ ☆ ★∵ ..../ 
  ◥█▅▅██▅▅██▅▅▅▅▅███◤ 
   .◥███████████████◤
~~~~◥█████████████◤~~~~
*/
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;

inline int read()
{
	int x=0,f=1;char s=getchar();
	while('0'>s||s>'9') {if(s=='-')f=-1;s=getchar();}
	while('0'<=s&&s<='9') {x=x*10+s-'0';s=getchar();}
	return x*f;
}

int n;
int a[100007];

inline int max(int a,int b) {return a>b?a:b;}

struct node{
	int a,b;
}e[100007*20];
int tot=1;

inline void build(int x)
{
	int p=1;
	for(int i=30;i>=0;i--) {
		int tmp=x&(1<<i);
		if(tmp)
			if(!e[p].a)
				e[p].a=++tot,p=tot;
			else p=e[p].a;
		else
			if(!e[p].b) e[p].b=++tot,p=tot;
			else p=e[p].b;
	}
}

inline int query(int x)
{
	int p=1;
	int ans=0;
	for(int i=30;i>=0;i--) {
		int tmp=x&(1<<i);
		if(!tmp) {
			if(e[p].a) p=e[p].a,ans+=(1<<i);
			else p=e[p].b;
		}
		else {
			if(e[p].b)	p=e[p].b;
			else p=e[p].a,ans+=(1<<i);
		}
	}
	return ans^x;
}

int main()
{
	while(scanf("%d",&n)==1) {
		memset(e,0,sizeof(e));
		int ans=-0x3f3f3f3f;
		for(int i=1;i<=n;++i)
			a[i]=read(); 
		for(int i=1;i<=n;++i)
			build(a[i]);
		for(int i=1;i<=n;++i)
			ans=max(ans,query(a[i]));
		printf("%d\n",ans);	
	}
	return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM