zoukankan      html  css  js  c++  java
  • 【算法竞赛进阶指南】字典树 The XOR Largest Pair

    题目链接

    题意

    给出 N 个数字,任意选择两个数字进行异或运算,求结果最大值。

    思路

    我们对于每个数字求与其异或得到的最大值,求这 N 个最大值的最大值。

    把每个数字看做一个长度为 32 的二进制串,将其翻转,更新到 trie 中。

    对于每个二进制串 (S),遍历其值 (S_i)
    在 trie 中每次都尝试向下访问与 (S_i) 相反的字符。
    如果能向下访问那么向下访问,当前数字增加 (1LL<<(31-i)) ( 字符下标从 0 开始),
    否则向下访问与当前字符相同的节点。

    代码

    #include<bits/stdc++.h>
    typedef long long ll;
    using namespace std;
    const ll N=2e6+10;
    
    ll arr[N];
    int tot=1,trie[N][2];
    ll s[N];
    void insert()
    {
    	ll p=1;
    	for(ll i=0;i<32;i++){
    		ll now=s[i];
    		if(!trie[p][now]){
    			trie[p][now]=++tot;
    		}
    		p=trie[p][now];
    	}
    }
    
    ll solve()
    {
    	ll rel=0,p=1,cnt=31;
    	for(ll i=0;i<32;i++,cnt--){
    		ll now=1^s[i];
    		if(trie[p][now]){
    			rel+=(1LL<<cnt);
    		}else{
    			now=s[i];
    		}
    		p=trie[p][now];
    	}	
    	return rel;
    }
    
    int main()
    {
    	ll n,rel=0;
    	scanf("%lld",&n);
    	for(ll i=1;i<=n;i++){
    		scanf("%lld",&arr[i]);
    		for(ll j=0;j<32;j++){
    			s[31-j]=(arr[i]&(1LL<<j))?1:0;
    		}
    		insert();
    		rel=max(rel,solve());
    	}
    	printf("%lld
    ",rel);
    	return 0;
    }
    
  • 相关阅读:
    eclipse安装Aptana 插件,支持Javascript
    C++字符串转换成uint64类型
    C语言字节对齐
    Windows版本Traceroute
    ubuntu下使用FireBug调试Javascript脚本
    TCP拥塞控制图
    nodejs点滴
    你应该知道的16个Linux服务器监控命令
    C语言运算符(转载)
    常用正则表达式
  • 原文地址:https://www.cnblogs.com/valk3/p/13917929.html
Copyright © 2011-2022 走看看