hdu 4828 Xor Sum (trie 树模板题,经典应用)

hdu 4825 题目链接

题意:给定n个数,然后给出m个询问,每组询问一个数x,问n中的数y使得x和y的异或和最大。

思路:字典树。。把每个数转化成二进制,注意补全前导0,使得所有数都有相同的位数。

如果想要异或和最大,那么每一位尽可能都是1.

所以做法是,先构建字典树,然后每次find的时候,尽可能按照和当前寻找的数的位相反的位的方向走(如果有的话)

比如当前位是1,那我就往0的方向走。

需要注意的是,多组数据,每次要重新初始化一遍。

做法是 在struct 中重新 root = new Node() 一下。。这样就重新调用了Node中初始化用的构造函数。

  1/* ***********************************************
  2Author :111qqz
  3Created Time :2016年08月15日 星期一 20时03分05秒
  4File Name :code/hdu/4825.cpp
  5************************************************ */
  6#include <cstdio>
  7#include <cstring>
  8#include <iostream>
  9#include <algorithm>
 10#include <vector>
 11#include <queue>
 12#include <stack>
 13#include <set>
 14#include <map>
 15#include <string>
 16#include <cmath>
 17#include <cstdlib>
 18#include <deque>
 19#include <ctime>
 20#define fst first
 21#define sec second
 22#define lson l,m,rt<<1
 23#define rson m+1,r,rt<<1|1
 24#define ms(a,x) memset(a,x,sizeof(a))
 25typedef long long LL;
 26#define pi pair < int ,int >
 27#define MP make_pair
 28using namespace std;
 29const double eps = 1E-8;
 30const int dx4[4]={1,0,0,-1};
 31const int dy4[4]={0,-1,1,0};
 32const int inf = 0x3f3f3f3f;
 33const int LEN = 32;
 34int n,m;
 35char str[35];
 36struct Trie
 37{
 38    struct Node
 39    {
 40	Node *nxt[2];
 41	int val;
 42	Node()
 43	{
 44	    for ( int i = 0 ; i < 2 ; i++) nxt[i]=NULL;
 45	    val = 0 ;
 46	}
 47    };
 48    Node *root;
 49    void init()
 50    {
 51	root = new Node();
 52    }
 53    Trie()
 54    {
 55	root = new Node();
 56    }
 57    void Insert(char *s,int num)
 58    {
 59	Node *u =root;
 60	int len = strlen(s);
 61//	cout<<" len :"<<len<<endl;
 62	for ( int i = 0 ; i < len ; i++)
 63	{
 64	    int v = s[i]-'0';
 65	    if (u->nxt[v]==NULL) u->nxt[v] = new Node();
 66	    u = u->nxt[v];
 67	}
 68	u->val = num;
 69    }
 70    int Find(char *s)
 71    {
 72	Node *u = root;
 73	int len = strlen(s);
 74	for ( int i = 0 ; i < len ; i++)
 75	{
 76	    int x = s[i]-'0';
 77	    int y = !x;
 78	    if (u->nxt[y]==NULL)  //相反的方向有路就走相反的,没路就只能走一样的。
 79		u = u->nxt[x];
 80	    else u = u->nxt[y];
 81	}
 82	return u->val;
 83    }
 84}trie;
 85void bianshen( int x)
 86{
 87    for ( int i = LEN-1,j=0 ; i>=0 ; i--,j++) //高位补0,以及str[0]是最高位,str[LEN-1]是最低位
 88	str[i] =((x>>j)&1)+'0';
 89}
 90int main()
 91{
 92	#ifndef  ONLINE_JUDGE 
 93	freopen("code/in.txt","r",stdin);
 94  #endif
 95	int T;
 96	cin>>T;
 97	int cas = 0 ;
 98	while (T--)
 99	{
100	    trie.init();
101	    printf("Case #%d:\n",++cas);
102	    scanf("%d%d",&n,&m);
103	    for ( int i = 1 ; i <= n ; i++)
104	    {
105		int x;
106		scanf("%d",&x);
107		bianshen(x);
108		trie.Insert(str,x);		
109	    }
110	    while (m--)
111	    {
112		int x;
113		scanf("%d",&x);
114		bianshen(x);
115		printf("%d\n",trie.Find(str));
116	    }
117	}
118  #ifndef ONLINE_JUDGE  
119  fclose(stdin);
120  #endif
121    return 0;
122}