HDU 6625 字典树 + 贪心

还可以字典树??

题目链接

题意

给你两个序列,第三个序列是由已知的两个序列对应位置异或而成,现在让你重新安排两个序列的位置,使得异或之后的第三个序列字典序最小。

思路

字典树真是万万没想到,我们把每个数字拆成二进制的形式建字典树,这样对两个序列能够建立两棵树,然后运用贪心思想,能够0,0或者1,1异或就先它们异或,这样进行下去,最后还要记得排序,因为每一步形成的数字不一定是当前步的最优解。同时注意这题初始化不要全初始化,用到某个节点,我们再对某个节点初始化,否则会T

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string>
#include <cstring>
#include <queue>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 5;
int tot,n;
struct tree{
int tree[maxn * 30][3], sum[maxn * 30];
int newnode()
{
tot++;
memset(tree[tot], 0, sizeof(tree[tot]));
return tot;
}
void insert(int num)
{
int p = 0;
for(int i = 29; i >= 0; --i)
{
int x = (1 << i) & num;
if(x > 0) x = 1;
else x = 0;
if(!tree[p][x])
tree[p][x] = newnode();
sum[tree[p][x]]++;
p = tree[p][x];
}
}
}a1, a2;
int ans[100005];
void init()
{
memset(a1.tree[0], 0, sizeof(a1.tree[0]));
memset(a2.tree[0], 0, sizeof(a2.tree[0]));
}
int ant ;
void solve()
{
while(n--)
{
int p1 = 0, p2 = 0, x = 0;
for(int i = 29; i >= 0; --i)
{
if(a1.sum[a1.tree[p1][0]] && a2.sum[a2.tree[p2][0]])
{
a1.sum[a1.tree[p1][0]]--;
a2.sum[a2.tree[p2][0]]--;
p1 = a1.tree[p1][0];
p2 = a2.tree[p2][0];
}
else if(a1.sum[a1.tree[p1][1]] && a2.sum[a2.tree[p2][1]])
{
a1.sum[a1.tree[p1][1]]--;
a2.sum[a2.tree[p2][1]]--;
p1 = a1.tree[p1][1];
p2 = a2.tree[p2][1];
}
else if(a1.sum[a1.tree[p1][0]] && a2.sum[a2.tree[p2][1]])
{
a1.sum[a1.tree[p1][0]]--;
a2.sum[a2.tree[p2][1]]--;
p1 = a1.tree[p1][0];
p2 = a2.tree[p2][1];
x ^= (1 << i);
}
else if(a1.sum[a1.tree[p1][1]] && a2.sum[a2.tree[p2][0]])
{
a1.sum[a1.tree[p1][1]]--;
a2.sum[a2.tree[p2][0]]--;
p1 = a1.tree[p1][1];
p2 = a2.tree[p2][0];
x ^= (1 << i);
}
}
ans[++ant] = x;
}
}

int main()
{
int T;
scanf("%d",&T);
while(T--)
{
tot = 0, ant = 0;
scanf("%d",&n);
init();
for(int i = 1, x; i <= n; ++i)
{
scanf("%d",&x);
a1.insert(x);
}
for(int i = 1, x; i <= n; ++i)
{
scanf("%d",&x);
a2.insert(x);
}
solve();
sort(ans + 1, ans + ant + 1);
for(int i = 1; i <= ant; ++i)
{
printf("%d%c",ans[i], i == ant ? '\n':' ');
}
}
}