[2019杭电多校第五场][hdu6625]three arrays(01字典树)

Posted sainsist

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[2019杭电多校第五场][hdu6625]three arrays(01字典树)相关的知识,希望对你有一定的参考价值。

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6625

大意为给你两个数组a和b,对应位置异或得到c数组,现在可以将a,b数组从新排序求c数组,使得字典序最小。

大致的做法就是用两个数组中的数字二进制 建两颗字典树,同时记录每个位置的个数。然后在两颗字典树上同时dfs,优先往0-0和1-1方向走,不能走再走0-1,1-0方向。

因为0-0和1-1两种情况不分先后,所以走出来的不一定是最小的,走完得到的c数组要排序。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<string>
 5 #include<algorithm>
 6 using namespace std;
 7 typedef long long ll;
 8 const int maxn = 100000 + 5;
 9 struct Trie 
10     int tree[maxn * 30][2], num[maxn * 30];
11     int len, root;
12     int newcode() 
13         tree[len][0] = tree[len][1] = 0;
14         num[len] = 0;
15         return len++;
16     
17     void init() 
18         len = 0;
19         root = newcode();
20     
21     void insert(int x) 
22         int now = root;
23         for (int i = 29; i >= 0; i--) 
24             int k = (x >> i) & 1;
25             if (!tree[now][k])
26                 tree[now][k] = newcode();
27             now = tree[now][k];
28             num[now]++;
29         
30     
31 A, B;
32 int ans[maxn];
33 void slove(int n) 
34     for (int i = 1; i <= n; i++) 
35         ans[i] = 0;
36         int nowA = 0, nowB = 0;
37         for (int j = 29; j >= 0; j--) 
38             if (A.num[A.tree[nowA][0]] && B.num[B.tree[nowB][0]]) 
39                 nowA = A.tree[nowA][0], nowB = B.tree[nowB][0];
40                 A.num[nowA]--, B.num[nowB]--;
41             
42             else if (A.num[A.tree[nowA][1]] && B.num[B.tree[nowB][1]]) 
43                 nowA = A.tree[nowA][1], nowB = B.tree[nowB][1];
44                 A.num[nowA]--, B.num[nowB]--;
45             
46             else if (A.num[A.tree[nowA][0]] && B.num[B.tree[nowB][1]]) 
47                 nowA = A.tree[nowA][0], nowB = B.tree[nowB][1];
48                 A.num[nowA]--, B.num[nowB]--;
49                 ans[i] += (1 << j);
50             
51             else if (A.num[A.tree[nowA][1]] && B.num[B.tree[nowB][0]]) 
52                 nowA = A.tree[nowA][1], nowB = B.tree[nowB][0];
53                 A.num[nowA]--, B.num[nowB]--;
54                 ans[i] += (1 << j);
55             
56         
57     
58 
59 int main() 
60     int t;
61     scanf("%d", &t);
62     while (t--) 
63         int n, x;
64         A.init(), B.init();
65         scanf("%d", &n);
66         for (int i = 1; i <= n; i++)
67             scanf("%d", &x), A.insert(x);
68         for (int i = 1; i <= n; i++)
69             scanf("%d", &x), B.insert(x);
70         slove(n);
71         sort(ans + 1, ans + 1 + n);
72         for (int i = 1; i <= n; i++)
73             printf("%d%c", ans[i], i == n ? \n :  );
74     
75 
76 

 

以上是关于[2019杭电多校第五场][hdu6625]three arrays(01字典树)的主要内容,如果未能解决你的问题,请参考以下文章

[2019杭电多校第五场][hdu6624]fraction

[2019杭电多校第五场][hdu6628]permutation 1

[2019杭电多校第五场][hdu6629]string matching

[2019杭电多校第五场][hdu6630]permutation 2

2019 杭电多校 第五场

2020杭电多校第五场1012-Set1