『字典树』xor

题目描述

给出 n 个数 a1..an,求 ai xor aj, (i不等于j) 的最大值

输入

第一行一个数 n

接下一行 个数 a1..an

输出

一行一个数 ans, 表示 axor aj(i不等于j) 的最大值

样例输入
4
3 6 7 7
样例输出
5
提示

• 对于 30% 的数据, n ≤ 1000。

• 对于另外 20% 的数据,数据保证最后的 ans 一定是 2k − 1。

• 对于 70% 的数据, n ≤ 10^5, 0 ≤ ai ≤ 10^7。

• 对于 100% 的数据, n ≤ 10^5, 0 ≤ ai ≤ 10^16。


『题解』字典树,每次找不相等的。

#include
    
    
     
     
#include
     
     
      
      
#include
      
      
       
       
#include
       
       
        
        
 
 
using namespace std;
 
 
struct reads
{
	long long x;
	int num[100], t;	
}p[100100];
 
 
struct trees
{
	int leftson, rightson, v, b;
	trees() {
		v = INT_MAX;
	}
}tree[5000100];
 
 
long long tot = 1, Ans = 0;
int Max = 0;
 
 
int change(int i)
{
	long long x = p[i].x;
	while (x != 0)
	{
		p[i].num[++p[i].t] = x % 2;
		x /= 2;
	}
	return 0;
}
 
 
int build(int i)
{
	int t = Max, tel = 1;
	while (t >= 1)
	{
		if (tree[tel].leftson!= 0 && p[i].num[t] == tree[tree[tel].leftson].v)
			tel = tree[tel].leftson;
		else
			if (tree[tel].rightson!= 0 && p[i].num[t] == tree[tree[tel].rightson].v)
				tel = tree[tel].rightson;
			else
			{
				if (tree[tel].rightson == 0)
				{
					tree[tel].rightson = ++ tot;
					tree[tree[tel].rightson].v = p[i].num[t];
					tel = tree[tel].rightson;
				}
				else
				{
					tree[tel].leftson = ++ tot;
					tree[tree[tel].leftson].v = p[i].num[t];
					tel = tree[tel].leftson;
				}
			}
		t--;
	}
	tree[tel].b = 1;
	return 0;
}
 
 
int check(int i)
{
	long long num = 0;
	int tel = 1, t = Max;
	while (t >= 1)
	{
		if (tree[tel].leftson != 0 && tree[tree[tel].leftson].v != p[i].num[t])
		{
			tel = tree[tel].leftson;
			(num *= 2) += 1;
			t--; 
			continue;
		}
		if (tree[tel].rightson != 0 && tree[tree[tel].rightson].v != p[i].num[t])
		{
			tel = tree[tel].rightson;
			(num *= 2) += 1;
			t--; 
			continue;
		}
		if (tree[tel].leftson == 0 && tree[tree[tel].rightson].v == p[i].num[t])
		{
			tel = tree[tel].rightson;
			num *= 2;
			t--; 
			continue;
		}
		if (tree[tel].rightson == 0 && tree[tree[tel].leftson].v == p[i].num[t])
		{
			tel = tree[tel].leftson;
			num *= 2;
			t--; 
			continue;
		}
	}
	Ans = max(Ans, num);
	return 0;
}
 
 
int main(void)
{
    freopen("xor.in","r",stdin);
    freopen("xor.out","w",stdout);
    
    int n;
    cin >> n;
    for (int i = 1;i <= n; i++)
    {
    	scanf("%lld", &p[i].x);
    	change(i);
    	Max = max(Max, p[i].t);
    }
    tree[1].v = 0;
    for (int i = 1;i <= n; i++)
    	build(i);
    for (int i = 1;i <= n; i++)
    	check(i);
    cout << Ans;
    
    fclose(stdin);
    fclose(stdout);
    return 0;
}
       
       
      
      
     
     
    
    


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值