题意:
给你一组数,开始询问给一个数 求组中与该数异或值最大的数。
分析:根据异或的特点 要想得到的异或值最大 尽可能的让两个数的每位都相反 先把给定的一组数建树,数的最后一位对应的节点保存这个数的位置(放便取) 对于每个询问 在搜树时优先考虑和当前数位相反的节点。
#include <map> #include <set> #include <list> #include <cmath> #include <queue> #include <stack> #include <cstdio> #include <vector> #include <string> #include <cctype> #include <complex> #include <cassert> #include <utility> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> using namespace std; typedef pair<int,int> PII; typedef long long ll; #define lson l,m,rt<<1 #define pi acos(-1.0) #define rson m+1,r,rt<<11 #define All 1,N,1 #define read freopen("in.txt", "r", stdin) #define N 4000010 const ll INFll = 0x3f3f3f3f3f3f3f3fLL; const int INF= 0x7ffffff; const int mod = 1000000007; struct Trie{ ll ch[N][3],num; int val[N]; void init(){ num=1; memset(ch[0],0,sizeof(ch[0])); } void build(ll x,int id){ int u=0; for(int i=32;i>=0;i--){ int v=(x&(1LL<<i))>0; if(!ch[u][v]){ memset(ch[num],0,sizeof(ch[num])); val[num]=0; ch[u][v]=num++; } u=ch[u][v]; } val[u]=id; } int query(ll x){ int u=0; for(int i=32;i>=0;i--){ int v=(x&(1LL<<i))>0; if(ch[u][!v]){ u=ch[u][!v]; } else{ u=ch[u][v]; } } return val[u]; } }trie; int main() { int t,n,m; ll a[100010]; scanf("%d",&t); for(int o=1;o<=t;++o){ trie.init(); printf("Case #%d:\n",o); scanf("%d%d",&n,&m); for(int i=1;i<=n;++i){ scanf("%I64d",&a[i]); trie.build(a[i],i); } ll s; for(int i=0;i<m;++i){ scanf("%I64d",&s); printf("%I64d\n",a[trie.query(s)]); } } return 0; }
时间: 2024-10-27 11:32:36