zoukankan      html  css  js  c++  java
  • D. Dr. Evil Underscores

    题意:今天,作为一个友谊礼物,Bakry给予Badawy n个整数a1,a2,...,an,让他去寻找一个数X,使得(underset{1 leq i leq n}{max} (a_i oplus X))最小。

    输入:
    第一行是一个整数n(1 <= n <= 10^5)
    第二行是n个整数a1,a2,...,an(0 <= ai <= 2^30 - 1)

    输出:
    (underset{1 leq i leq n}{max} (a_i oplus X))的最小值

    分析:对于异或最大值,我们可以采用字典树存储每个整数的01串,如果我们要去找一个数X,去查询和每个数的异或最大值,然后比较所有的异或最大值,枚举所有的x,这样会导致超时。我们可以去寻找一种更加棒的方法,当我们去遍历一颗trie树的时候,从高往低遍历每一位,每个结点都有1~2个分支,如果只有一个分支,我们用x异或的时候,我们贪心地希望x这位和这个结点的值相等,这样,我们所能得到的异或最大值会最小,如果有两个分支怎么办,我们去递归求解这两个分支,取一个min,就能得到最小值,同时,我们可以发现,我们可以在递归的时候,顺便把这个最大值求解出来,当只有一个分支的时候,意味着我们要去选择一个x,它的这位是和这个分支的位相等,意味着值为0,如果有两个分支,因为我们求解的是最大值,所以,我们会加上1 << k,这样,我们就可以得到最大值最小了。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <algorithm>
     
    using namespace std;
    using LL = long long;
    const int N = 3200005;
    const int M = 100005;
     
    int trie[N][2], idx;
    int a[M];
     
    void insert(int x)
    {
    	int p = 0;
    	for (int i = 29; i >= 0; --i)
    	{
    		int u = x >> i & 1;
    		if (!trie[p][u]) trie[p][u] = ++idx;
    		p = trie[p][u];
    	}
    }
     
    int solve(int cur, int k)
    {
    	if (k == -1)
    		return 0;
    	if (trie[cur][0] == 0)
    		return solve(trie[cur][1], k - 1);
    	else if (trie[cur][1] == 0)
    		return solve(trie[cur][0], k - 1);
    	else
    	{
    		return (1 << k) + min(solve(trie[cur][1], k - 1), solve(trie[cur][0], k - 1));
    	}
     
    }
     
    int main()
    {
    	int n;
    	scanf("%d", &n);
     
    	for (int i = 1; i <= n; ++i)
    	{
    		scanf("%d", &a[i]);
    		insert(a[i]);
    	}
     
    	int ans = solve(0, 29);
     
    	cout << ans << endl;
    		
    	return 0;
    }
    
    
  • 相关阅读:
    Eclipse 代码模板
    Eclipse 安装插件
    Eclipse 任务管理
    Eclipse 添加书签
    Eclipse 重构菜单
    Eclipse 浏览(Navigate)菜单浏览 Eclipse 工作空间
    Eclipse 查找
    Eclipse 悬浮提示
    Eclipse 快速修复
    Eclipse 内容辅助
  • 原文地址:https://www.cnblogs.com/pixel-Teee/p/12207024.html
Copyright © 2011-2022 走看看