• 字典树!


    A - Xor Sum

    Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包含了N个正整数,随后 Prometheus 将向 Zeus 发起M次询问,每次询问中包含一个正整数 S ,之后 Zeus 需要在集合当中找出一个正整数 K ,使得 K 与 S 的异或结果最大。Prometheus 为了让 Zeus 看到人类的伟大,随即同意 Zeus 可以向人类求助。你能证明人类的智慧么? 

    Input输入包含若干组测试数据,每组测试数据包含若干行。 
    输入的第一行是一个整数T(T < 10),表示共有T组数据。 
    每组数据的第一行输入两个正整数N,M(<1=N,M<=100000),接下来一行,包含N个正整数,代表 Zeus 的获得的集合,之后M行,每行一个正整数S,代表 Prometheus 询问的正整数。所有正整数均不超过2^32。Output对于每组数据,首先需要输出单独一行”Case #?:”,其中问号处应填入当前的数据组数,组数从1开始计算。 
    对于每个询问,输出一个正整数K,使得K与S异或值最大。Sample Input

    2
    3 2
    3 4 5
    1
    5
    4 1
    4 6 5 6
    3

    Sample Output

    Case #1:
    4
    3
    Case #2:
    4
    调了一下午的程序!太snake了! 这个字典树建树是好建的,但是查询就很烦了。
    首先,数字默认的整数类型是longint,所以你1<<32 会爆longint(1<<32=1)(1<<31=-maxlongint),那怎么做?令(int64)k=1,k<<32,
    就不会爆了

    其次在用function 的时候,每一层都会返回一个值!如果你不手动让它返回一个值,那它就会自作主张地随机返回一个值,得到的答案就是错的!
    (经检验,procedure 不会有这种情况发生,只要不死循环)
    另外,数组大小要计算好,每个数字最大32位,<n*32 的空间要开,尽量开大点空间,在不爆的前提下!
     1 var
     2 l,t,i:longint;
     3 tree:array[0..2000005,0..1]of int64;
     4 
     5 x,y,tot,n,m,ans:int64;
     6 procedure insert(u:int64);
     7  var i:longint; val,now,k:int64;
     8   begin
     9   now:=0; val:=0;
    10 
    11   for i:=32 downto 0 do
    12    begin
    13    k:=1;    k:=k<<i;
    14     if  (k and u)<>0 then val:=1 else val:=0;
    15     if  tree[now,val]=-1 then
    16      begin
    17        inc(tot);
    18        tree[now,val]:=tot;
    19      end;
    20      now:=tree[now,val];
    21    //  inc(num[now]);
    22    end;
    23 
    24  end;
    25  function find(i,now,u:int64):int64;
    26    var k,tmp:int64;
    27  begin
    28    //writeln(i ,' ',ans);
    29   if i<0 then exit(ans);
    30   k:=1; k:=k<<i;
    31        if (k and u)<>0 then
    32         begin
    33         // writeln(((1<<i)and u));
    34           if tree[now,0]<>-1 then
    35           begin
    36         //  if tree[now,0]<>0 then   ans:=ans+k;
    37             tmp:=find(i-1,tree[now,0],u);
    38           end
    39            else
    40            begin
    41              ans:=ans+k;
    42              tmp:=find(i-1,tree[now,1],u);
    43            end;
    44         end else
    45           if (k and u)=0 then
    46            if tree[now,1]<>-1 then
    47             begin
    48               ans:=ans+k;
    49               tmp:=find(i-1,tree[now,1],u);
    50             end
    51            else
    52              begin
    53               // ans:=ans+tree[now,0]>>i;
    54                tmp:=find(i-1,tree[now,0],u);
    55              end;
    56     exit(tmp);//使每层都有返回值的操作
    57   end;
    58 begin
    59 readln(t);
    60 for l:=1 to t do
    61 begin
    62 fillchar(tree,sizeof(tree),255);
    63 tot:=0;
    64 readln(n,m);
    65  for i:=1 to n do
    66  begin
    67     read(x);
    68     insert(x);
    69  end;
    70   writeln('Case #',l,':');
    71  for i:=1 to m do
    72   begin
    73     readln(y);
    74     ans:=0;
    75 
    76     writelN(find(32,0,y));
    77   end;
    78 end;
    79 end.

    NOIP2018 rp++
  • 相关阅读:
    [git] git 的基本认知
    [Java] Java IO Files
    [Java] Java IO 概况
    [Java] JavaMail 发送带图片的 html 格式的邮件
    [Java] HashMap 导致的高 CPU 使用率
    [Struts] Hello World Demo
    [Hibernate] 注解映射例子
    [Hibernate] List 映射例子
    cmd的xcopy命令
    wpf custom control
  • 原文地址:https://www.cnblogs.com/brilliant107/p/9449970.html
Copyright © 2020-2023  润新知