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.