three arrays HDU - 6625 (字典树)
three arrays
\]
题意
给出 \(a\),\(b\) 数组,定义数组 \(c[i] = a[i] XOR b[i]\),现在可以任意调整 \(a\) 和 \(b\) 的顺序,使得最后的 \(c\) 字典序最小。
思路
对于 \(a\) 数组和 \(b\) 数组分别建立字典树,然后从大到小在字典树上贪心构造尽量小的 \(c\)。
对于某一位,如果两颗树上同时有 \(00\) 或者 \(11\),那么就选择往这样的边 \(dfs\),否则的话往 \(01\) 或者 \(10\) 去 \(dfs\),并加上这一位的异或值。
因为 \(01\) 和 \(10\) 不可能同时出现,因为如果同时出现了,肯定优先去 \(00\) 或者 \(11\)。那么就是 \(00\) 和 \(11\) 的情况,可能出现往 \(00\) 的答案是 \(4\),往 \(11\) 的答案是 \(3\),那么无法让小的先出来,所以可以任一选一个走,把另一个留到后面走,然后对于所有求出来的 \(c\) 在 \(sort\) 一遍。
/***************************************************************
> File Name : a.cpp
> Author : Jiaaaaaaaqi
> Created Time : Fri 06 Sep 2019 09:17:26 PM CST
***************************************************************/
#include <map>
#include <set>
#include <list>
#include <ctime>
#include <cmath>
#include <stack>
#include <queue>
#include <cfloat>
#include <string>
#include <vector>
#include <cstdio>
#include <bitset>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define lowbit(x) x & (-x)
#define mes(a, b) memset(a, b, sizeof a)
#define fi first
#define se second
#define pb push_back
#define pii pair<int, int>
typedef unsigned long long int ull;
typedef long long int ll;
const int maxn = 1e5 + 10;
const int maxm = 1e5 + 10;
const ll mod = 1e9 + 7;
const ll INF = 1e18 + 100;
const int inf = 0x3f3f3f3f;
const double pi = acos(-1.0);
const double eps = 1e-8;
using namespace std;
int n, m;
int cas, tol, T;
int tot[2];
int a[maxn], b[maxn], c[maxn];
int node[2][maxn*30][2], cnt[2][maxn*30];
void insert(int x, int id) {
int rt = 0;
for(int i=30; i>=1; i--) {
int f = (x&(1<<(i-1))) ? 1 : 0;
if(node[id][rt][f] == 0) {
tot[id]++;
mes(node[id][tot[id]], 0);
cnt[id][tot[id]] = 0;
node[id][rt][f] = tot[id];
}
rt = node[id][rt][f];
cnt[id][rt]++;
}
}
int dfs(int rt1, int rt2, int p) {
// printf("rt1=%d rt2=%d\n", rt1, rt2);
if(p == 0) return 0;
bool ok00 = (node[0][rt1][0] && cnt[0][node[0][rt1][0]]);
bool ok01 = (node[0][rt1][1] && cnt[0][node[0][rt1][1]]);
bool ok10 = (node[1][rt2][0] && cnt[1][node[1][rt2][0]]);
bool ok11 = (node[1][rt2][1] && cnt[1][node[1][rt2][1]]);
if(ok00 && ok10) {
cnt[0][node[0][rt1][0]]--, cnt[1][node[1][rt2][0]]--;
return dfs(node[0][rt1][0], node[1][rt2][0], p-1);
} else if(ok01 && ok11) {
cnt[0][node[0][rt1][1]]--, cnt[1][node[1][rt2][1]]--;
return dfs(node[0][rt1][1], node[1][rt2][1], p-1);
} else if(ok00 && ok11) {
cnt[0][node[0][rt1][0]]--, cnt[1][node[1][rt2][1]]--;
return dfs(node[0][rt1][0], node[1][rt2][1], p-1) + (1<<(p-1));
} else {
cnt[0][node[0][rt1][1]]--, cnt[1][node[1][rt2][0]]--;
return dfs(node[0][rt1][1], node[1][rt2][0], p-1) + (1<<(p-1));
}
}
int main() {
// freopen("in", "r", stdin);
scanf("%d", &T);
while(T--) {
cnt[0][0] = cnt[1][0] = tot[0] = tot[1] = 0;
mes(node[0][0], 0), mes(node[1][0], 0);
scanf("%d", &n);
for(int i=1; i<=n; i++) scanf("%d", &a[i]), insert(a[i], 0);
for(int i=1; i<=n; i++) scanf("%d", &b[i]), insert(b[i], 1);
for(int i=1; i<=n; i++) c[i] = dfs(0, 0, 30);
sort(c+1, c+1+n);
for(int i=1; i<=n; i++) printf("%d%c", c[i], i==n ? '\n' : ' ');
}
return 0;
}
three arrays HDU - 6625 (字典树)的更多相关文章
- [2019杭电多校第五场][hdu6625]three arrays(01字典树)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6625 大意为给你两个数组a和b,对应位置异或得到c数组,现在可以将a,b数组从新排序求c数组,使得字典 ...
- HDU 5687 字典树插入查找删除
题目:http://acm.hdu.edu.cn/showproblem.php?pid=5687 2016百度之星资格赛C题,直接套用字典树,顺便巩固了一下自己对字典树的理解 #include< ...
- HDU 5384 字典树、AC自动机
题目:http://acm.hdu.edu.cn/showproblem.php?pid=5384 用字典树.AC自动机两种做法都可以做 #include<stdio.h> #includ ...
- hdu 2112(字典树+最短路)
HDU Today Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- hdu 2072(字典树模板,set,map均可做)
地址:http://acm.hdu.edu.cn/showproblem.php?pid=2072 lily的好朋友xiaoou333最近很空,他想了一件没有什么意义的事情,就是统计一篇文章里不同单词 ...
- Chip Factory HDU - 5536 字典树(删除节点|增加节点)
题意: t组样例,对于每一组样例第一行输入一个n,下面在输入n个数 你需要从这n个数里面找出来三个数(设为x,y,z),找出来(x+y)^z(同样也可以(y+z)^1)的最大值 ("^&qu ...
- hdu 1251 字典树的应用
这道题看了大神的模板,直接用字典树提交的会爆内存,用stl 里的map有简单有快 #include <iostream> #include <map> #include < ...
- hdu 2896 字典树解法
#include <iostream> #include <cstring> #include <cstdio> #include <cstdlib> ...
- Repository HDU - 2846 字典树
题意:给出很多很多很多很多个 单词 类似搜索引擎一下 输入一个单词 判断有一个字符串包含这个单词 思路:字典树变体,把每个单词的后缀都扔字典树里面,这里要注意dd是一个单词 但是把d 和dd都放字典树 ...
随机推荐
- linux 软件多版本共存
update-alternatives 命令用于处理 Linux 系统中软件版本的切换,使其多版本共存.alternatives 的管理目录 /etc/alternatives . alternati ...
- golang学习 ---defer语句
golang语言defer特性详解 defer语句是go语言提供的一种用于注册延迟调用的机制,它可以让函数在当前函数执行完毕后执行,是go语言中一种很有用的特性.由于它使用起来简单又方便,所以深得go ...
- docker离线导入导出镜像
docker save -o mysqlies.tar 5ada6380f248(镜像id) # 镜像id是要导出的 有镜像的机器 在有镜像的机器上执行docker load --input ...
- 4、VUE生命周期
下面是分步骤解释vue生命周期 1.开始:new Vue() 创建vue对象过程还是比较繁琐的,所以创建vue对象是异步执行的. 回调函数:beforeCreate 2.Observe Data 监控 ...
- C#读写修改设置调整UVC摄像头画面-滚动
有时,我们需要在C#代码中对摄像头的滚动进行读和写,并立即生效.如何实现呢? 建立基于SharpCamera的项目 首先,请根据之前的一篇博文 点击这里 中的说明,建立基于SharpCamera的摄像 ...
- Visual C++ 2010 SP1 x86&x64
Microsoft Visual C++ 2010 SP1 Redistributable Package (x86) https://www.microsoft.com/en-us/download ...
- C# Linq 使用总结
隐式类型匿名类型自动属性初始化器委托泛型泛型委托匿名方法Lambda表达式扩展方法迭代器LINQ System.Linq var arr = new[] { "c", " ...
- VC 在桌面上绘制一些图形
注意:这是在桌面上绘制图形.如果想在VC++ MFC工程的视窗口上绘制图形.可以这么来,在工程View类的一个菜单响应(或者鼠标单击等事件的的响应)函数中添加下面main 中的代码,只需要将“红色字体 ...
- Middle English finaunce金融
Etymology finance From Middle English finaunce, a surety bond.A supply of money or goods. With thy b ...
- android 连接wifi案例
1.xml布局文件: <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmln ...