HDU 4825 01字典樹
阿新 • • 發佈:2019-02-05
題意:給定一個集合和多個詢問,每個詢問為一個數,輸出集合中的一個數使得該數與詢問的異或和最大。
思路:
經典題。
對於集合中的每一個數從高位到低位插入一棵01字典樹,然後對於每一個詢問的數
程式碼:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
const int A = 1e5 + 10;
int Trie[A*16][2],val[A*16],tot,n,m,x;
void init(){
tot = 0;
memset(val,0,sizeof(val));
memset (Trie,0,sizeof(Trie));
}
void insert(ll v){
int u = 0;
for(int i=32 ;i>=0 ;i--){
int c = (v>>i)&1;
if(!Trie[u][c]) Trie[u][c] = ++tot;
u = Trie[u][c];
}
val[u] = v;
}
int query(ll v){
int u = 0;
for(int i=32 ;i>=0 ;i--){
int c = (v>>i)&1 ;
if(Trie[u][c^1]) u = Trie[u][c^1];
else u = Trie[u][c];
}
return val[u];
}
int main(){
int T,_=1;T = read();
while(T--){
init();printf("Case #%d:\n",_++);
n = read();m = read();
for(int i=1 ;i<=n ;i++){x = read();insert(x);}
for(int i=1 ;i<=m ;i++){
x = read();
printf("%d\n",query(x));
}
}
return 0;
}