zoukankan      html  css  js  c++  java
  • 「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 }
  • 相关阅读:
    C#动态执行代码
    C#的动态编译执行
    Win7/Vista激活后添加grub引导Linux最简单方法!无需命令行!
    乔布斯:关于 Flash 的思考
    I want to live in a honest country
    twitter bbs
    my follow rule on twitter
    blog will be repleace by twitter?
    blog Prediction
    也说说对blog是否需要静态页面的一点看法
  • 原文地址:https://www.cnblogs.com/qwerta/p/9813624.html
Copyright © 2011-2022 走看看