[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 }

原文地址:https://www.cnblogs.com/sainsist/p/11354638.html

时间: 2024-08-02 12:36:30

[2019杭电多校第五场][hdu6625]three arrays(01字典树)的相关文章

2019 杭电多校 第五场

2019 Multi-University Training Contest 5 补题链接:2019 Multi-University Training Contest 5 罚时爆炸 自闭场 1004 equation (HDU 6627) 题意: 给定一个整数 \(C\) 和 \(N\) 组 \(a_i,b_i\),求 \(∑_{i=1}^N|a_i\cdot x + b_i| = C\) 的所有解,如果有无穷多个解就输出 -1. 思路 分类讨论 分类讨论去绝对值.根据 \(b_i / a_i

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

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6629 题意求字符串的每个后缀与原串的最长公共前缀之和. 比赛时搞东搞西的,还搞了个后缀数组...队友一说扩展kmp我都自闭了,这不就是扩展kmp的第一步,求原串的每个后缀与原串的最长公共前缀嘛. 需要注意的就是题目准确问的是按照文中所给的代码执行需要判断几次,如果最长公共前缀等于该后缀的长度,则会判断Next[i]次(Next[i]为以i为开始的后缀与原串的最长公共前缀).如果不等,则会判断Next

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

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6628 题意为求字典序第k小的差异数组,差异数组p满足p[i]=a[i+1]-a[i]. 头铁的爆搜,因为差异数组的范围为[1-n,n-1],所以爆搜的时候可以先将原数组每位+n,记录数字出现的上下界,最后求答案的时候再减去下界即可. 1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 using n

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

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6624 题意为求最小的b满足$a*b^{-1}\equiv x(modp)$. 把式子化简一下: $a\equiv b*x(modp)$ $a=b*x-p*y$ $\because 0<a<b$ $\therefore 0<b*x-p*y<b$ $0<b*x-p*y\Rightarrow \frac{p}{x}<\frac{b}{y}$ $b*x-p*y<b\Right

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

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6630 题意为求出1-n,n个数的全排列中有多少种方案满足第一位为x,第n位为y,且相邻数字绝对值之差不超过2. 我们可以预处理d数组,定义d[i]表示1-i个数的全排列中以1为第一位,i为第i位且相邻数字绝对值之差不超过2的方案数. 则第i位为i,可以由第i-1位转移,表示i位与i-1位数字绝对值之差为1,则$d[i]+=d[i-1]$,也可以由第i-3位转移,表示第i-1位为i-2,第i-2位为i

2019 杭电多校 第四场

2019 Multi-University Training Contest 4 补题链接:2019 Multi-University Training Contest 4 1001 AND Minimum Spanning Tree (HDU 6614) 题意 给定一个有 \(N\) 个结点的完全图,编号从 \(1\) 到 \(N\).结点 \(x\) 与结点 \(y\) \((1\leq x, y\leq N, x \neq y)\) 的边的权值为 \(x\) 与 \(y\) 按位与的值,求

[补]2019HDU杭电多校第五场H

红小豆又被奇怪的东西卡住了 参考于:思路https://www.cnblogs.com/st1vdy/p/11309280.html 样例https://www.cnblogs.com/dd-bond/p/11308155.html HDU-6631 line symmetric 多边形轴对称类问题.关于多边形轴对称目前可以公开的情报可见第一篇blog的大佬画的图,主要就是奇偶问题.本题主要思路是枚举实现找轴和验证对称,注意判自交的方式. 初步认识可以做一下hdu3902. 在下还是专注于讲心路

2019 杭电多校 第八场

2019 Multi-University Training Contest 8 补题链接:2019 Multi-University Training Contest 8 1003 Acesrc and Good Numbers HDU 6659 题意 定义 \(f(d, n)\) 为十进制下 \(1\) 到 \(n\) 所有数的数位中数字 \(d\) 出现的次数.给定 \(x\),找出最大的 \(n(n \le x)\) 满足 \(f(d, n) = n\). 题解 看到了一个神仙做法. 显

2019 杭电多校 第七场

2019 Multi-University Training Contest 7 补题链接:2019 Multi-University Training Contest 7 1001 A + B = C 题意: 给出 \(a, b, c\),求 \(x, y, z\) 满足 \(a\cdot 10^x + b\cdot 10^y = c\cdot 10^z\).\(a, b, c \le 10^{100000}\). 题解: 补零到 \(a, b, c\) 长度相等之后,可能的情况只有四种: \