入门oj 6451: The XOR Largest Pair之二

Description

今天小W用了1s不到的时候完成了这样一个题:
在给定的N个整数 A_1,A_2,…,A_N中选出两个进行异或运算,得到的结果最大是多少?
正当他志得意满时,L老师亮出了另一个题:
给你1000个数字a1到a1000,从其中选出三个数字ai,aj,ak
(1<=i,j,k<=1000,且i,j,k互不相同)
满足(ai+aj)xor ak的值最大
小W顿时迷茫了.........
 

Input

第一行给出数字N,接下来N行,每行一个数字

Output

如题

Sample Input

4
1
2
3
4

Sample Output

7

HINT

(1+2)xor4=7

sol 

trie题

具体做法:

1把每一个数字转为二进制,放入一个trie

2枚举每两个数的和,枚举一遍,因为是做异或运算,所以可以从高位往地位取(越高越好)

你会发现选的数字是不能重复的,所以要先把选的数从trie里面删掉

代码如下:

#include<cstring>
#include<iostream>
using namespace std;
const long long maxn=1e5+10;
long long a[310001][11],tot,sum[1001],End[maxn],ans;
char str[maxn];
void ins(long long str,long long vol)//如果vol==1 就是把一个数加进来,反之,就是删去那个数 
{
    long long p=0;
    for(long long i=31;i>=0;i--)
    {
        long long l=(str>>i)&1;
        if(!a[p][l])
            a[p][l]=++tot;
        p=a[p][l];
        End[p]+=vol;
    }//trie模板,不会自学 
}
long long find(long long str)
{
    long long p=0;
    long long ans=0;
    for(long long i=31;i>=0;i--)
    {
        long long l=(str>>i)&1;//算出第i位是几 
        if(a[p][l^1]) ans=ans<<1|1,p=a[p][l^1]; 
        else ans=ans<<1,p=a[p][l];//ans=ans<<1|1相当于在ans=ans<<1的第i位加1 
    }
    return ans;
}

int main(){
    long long n,m;
    cin>>n;
    tot=0;
    for(long long i=1;i<=n;i++)
       cin>>sum[i],ins(sum[i],1);
    for(long long i=1;i<=n;i++)
    for(long long j=i+1;j<=n;j++){
        ins(sum[i],-1);
        ins(sum[j],-1);//删除 
        ans=max(ans,find(sum[i]+sum[j]));
        ins(sum[i],1);
        ins(sum[i],1);//再加回来
    }

cout<<ans;
return 0;
}

 外送一个网址http://begin.lydsy.com/JudgeOnline/discuss3/thread.php?tid=735

you are both faker
原文地址:https://www.cnblogs.com/cwjr/p/12937084.html