OIIIIIIII

「LOJ#10050」「一本通 2.3 例 2」The XOR Largest Pair (Trie

题目描述

在给定的 $N$ 个整数 $A_1,A_2,A_3...A_n$ 中选出两个进行异或运算,得到的结果最大是多少?

输入格式

第一行一个整数$N$

第二行$N$个整数$A_i$

输出格式

一个整数表示答案。

样例

样例输入

5
2 9 5 7 0

样例输出

14

数据范围与提示

 对于$100%$的数据,$1≤N≤10^5$,$0≤Ai<2^{31}$。

 题解

这位朋友,你看这道题这样简洁,必然是很能拓展的题啊。

首先把每个数拆分二进制,从最高位(31位)开始,往0位走,算作一个字符串,丢到Trie里。

eg:$13->$

$[1][0][1][1][0][0]..............[0][0]$

$0<------------31$

然后循环每个数

对于一个数$x$,先拆二进制。

然后从最高位(31位)开始扫。

对于每一位,如果在Trie上对应走到了的点有与该位不同的支路(该位为0,支路为1/该位为1,支路为0),那就走。

则对答案的贡献为$(1<<i)$,所以$ans+=(1<<i)$($i$为当前位数)。

这样走出来的就是最优解了。

证明:如果在当前位能得到贡献而不走,之后就算每一位都能有贡献,$(1<<(j-1))+(1<<(j-2))+...+(1<<0) < (1<<j)$,也划不来。

所以贪心的去跑,最后得到的ans就是选这个$x$能得到的最优解了。

最后再记个max,即为答案。

 1 编号     题目     状态     分数     总时间     内存     代码 / 答案文件     提交者     提交时间
 2 #229998     #10050. 「一本通 2.32」The XOR Largest Pair    Accepted     100     218 ms     11388 KiB     C++ / 1.2 K     qwerta     2018-10-15 19:38:14
 3 
 4 #include<iostream>
 5 #include<cstring>
 6 #include<cstdio>
 7 using namespace std;
 8 struct emm{
 9     int nxt[2];
10 }a[3200013];//不会数数的傻子hzz一开始RE了好久qwq
11 int s[3200013];
12 int b[37];//用来拆二进制的数组
13 int main()
14 {
15     //freopen("data9.in","r",stdin);
16     int n;
17     scanf("%d",&n);
18     int cnt=0;
19     for(int i=1;i<=n;++i)
20     {
21         //cout<<i<<endl;
22         scanf("%d",&s[i]);//读入
23         //读了就丢进Trie
24         int x=s[i],g=-1;
25         memset(b,0,sizeof(b));
26         while(x)
27         {
28             b[++g]=x&1;
29             x>>=1;
30         }
31         int k=0;
32         for(int j=31;j>=0;--j)//从高往低建
33         {
34             if(!a[k].nxt[b[j]])
35             a[k].nxt[b[j]]=++cnt;
36             k=a[k].nxt[b[j]];
37         }
38     }
39     long long ans=0;
40     for(int i=1;i<=n;++i)
41     {
42         long long now=0;
43         int x=s[i],j=-1;//循环x
44         memset(b,0,sizeof(b));
45         while(x)
46         {
47             b[++j]=x&1;
48             x>>=1;
49         }
50         int k=0;
51         for(int j=31;j>=0;--j)
52         {
53             if(a[k].nxt[1-b[j]])//尽量往不一样的去走
54             {
55                 now+=(1<<j);
56                 k=a[k].nxt[1-b[j]];
57             }
58             else k=a[k].nxt[b[j]];
59         }
60         ans=max(ans,now);
61     }
62     cout<<ans;
63     return 0;
64 }

 

posted @ 2018-10-18 22:13  qwertaya  阅读(470)  评论(0编辑  收藏  举报
MDZX
Changsha
Fulan