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

题目:


给出两个数组a和b,可以任意调整a和b中元素的位置,使得最后的c数组的字典序最小,c[i] = a[i] ^ b[i]

解题思路:


先对a和b数组分别建立两棵01字典树,如图(省去了前面的很多位没有太大意义的0,此时max_base取3,因为最大的数才是3位的):

a数组的01字典树

b数组的01字典树

01字典树从上到下(即从高位到低位)的每一行的值表示,在这一堆数中,存在该位上为0/1的数。

同时遍历这两个01字典树,每次都贪心的找该位上同为0,或者同为1的节点,依次为基准再分别向下遍历,让每一位上都尽量同为0或者同为1,这样该位异或的时候才能得到0。若不存在该位上同为0或者1的情况,那么这一位就没法在a和b数组中找到两个数使得这一位的异或结果为0,那么就要更新答案。

一共要遍历n次,每次找到两个数使得他们的异或值是最小的,然后在01字典树上“删除”这了两个数(可在遍历的时候完成)

讲的有点啰嗦,参照代码和图模拟一遍就很清楚啦。

ac代码:


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+5;
const int max_base = 30;
int  ans[maxn];
struct node{int ch[32*maxn][2];int num[32*maxn];
}tree[2]; //两棵01字典树,不要忘记*32!!
int tol = 0;
void init(int type)
{tol = 1;tree[type].ch[0][0] = tree[type].ch[1][0] = 0;
}
void insert(int x, int type)
{int u = 0;for(int i = max_base; i >= 0; i--){int v = (x >> i & 1);if(!tree[type].ch[u][v]) // 新建节点{tree[type].ch[tol][1] = tree[type].ch[tol][0] = 0;tree[type].num[tol] = 0;tree[type].ch[u][v] = tol++;}u = tree[type].ch[u][v];tree[type].num[u]++;}
}
int query()
{int u0 = 0, u1 = 0, x = 0;for(int i = max_base; i >= 0; i--){int nxt0_0 = tree[0].ch[u0][0], nxt0_1 = tree[0].ch[u0][1], nxt1_0 = tree[1].ch[u1][0], nxt1_1 = tree[1].ch[u1][1];//下一行0,1对应的编号,若没有的话编号是0if(tree[0].num[nxt0_0] && tree[1].num[nxt1_0])//两棵字典树中都有数满足其第i位上是0{u0 = tree[0].ch[u0][0];u1 = tree[1].ch[u1][0];tree[0].num[nxt0_0]--;tree[1].num[nxt1_0]--;}else if(tree[0].num[nxt0_1] && tree[1].num[nxt1_1]){u0 = tree[0].ch[u0][1];u1 = tree[1].ch[u1][1];tree[0].num[nxt0_1]--;tree[1].num[nxt1_1]--;}else if(tree[0].num[nxt0_0] && tree[1].num[nxt1_1]){u0 = tree[0].ch[u0][0];u1 = tree[1].ch[u1][1];tree[0].num[nxt0_0]--;tree[1].num[nxt1_1]--;x += (1 << i);}else{u0 = tree[0].ch[u0][1];u1 = tree[1].ch[u1][0];tree[0].num[nxt0_1]--;tree[1].num[nxt1_0]--;x += (1 << i);}}return  x;
}
int main()
{//freopen("/Users/zhangkanqi/Desktop/11.txt","r",stdin);int t, n, x;scanf("%d", &t);while(t--){scanf("%d", &n);init(0);for(int i = 0; i < n; i++){scanf("%d", &x);insert(x, 0);}init(1);for(int i = 0; i < n; i++){scanf("%d", &x);insert(x, 1);}for(int i = 0; i < n; i++)ans[i] = query();sort(ans, ans + n);for(int i = 0; i < n; i++){if(i) printf(" ");printf("%d", ans[i]);}printf("\n");}return 0;
}

【2019杭电多校第五场1002=HDU6625】three arrays(01字典树+思维+贪心)相关推荐

  1. 2019杭电多校第9场1002 Rikka with Cake HDU6681

    2019杭电多校第9场1002 Rikka with Cake HDU6681 题意:给你若干个点按上下左右切割平面,最后问平面内有几块被切割开来. 解法1:红黑树+思维+贪心 A:根据欧拉定理可以得 ...

  2. 2019杭电多校 第七场 Kejin Player 6656(求期望值)

    2019杭电多校 第七场 Kejin Player 6656(求期望值) 题目 http://acm.hdu.edu.cn/showproblem.php?pid=6656 题意 给你n,q.表示有n ...

  3. 【2019.08.21】2019杭电多校第十场

    补题地址:http://acm.hdu.edu.cn/listproblem.php?vol=58 题号:6691-6701 1001: 1002: 1003:✅ 1004: 1005:✅ 1006: ...

  4. 2019 杭电多校第六场 题解

    比赛记录 注意随机数据 ,1-n排列这种,一般都有啥暴力重构之类的方法,期望重构次数很少之类的 1005也是这样,因为n^2但只有n个值有数,所以就可以n^2logn 题解 1001 Salty Fi ...

  5. 2019杭电多校第三场 6608 Fansblog(威尔逊定理+miller_rabin素性测试)

    Problem Description 传送门 Farmer John keeps a website called 'FansBlog' .Everyday , there are many peo ...

  6. 2019 杭电 多校第3场 1006 Fansblog (HDU 6608)

    题目链接 题解: 用威尔逊定理变换,然后求逆元. 代码: #include <bits/stdc++.h> using namespace std; typedef long long l ...

  7. hdu 6656 2019杭电多校第7场 期望题

    设f[i]为从i升级到i+1期望需要的金钱,由于每级都是能倒退或者升级到i+1,所以询问从l,r的期望金钱可以直接前缀和,那么推导每一级升级需要的期望钱也可以用前缀和推导 设sum[i]=f[1]+f ...

  8. 2019杭电多校第7场 K Kejin Player HDU 6656(数学推导)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6656 题目大意:对于每一个等级,可以花ai元,有pi概率升级,如果升级失败就退到xi级,问从li级升到 ...

  9. 2019杭电多校第七场 HDU - 6656 Kejin Player 期望

    题目链接:https://vjudge.net/problem/HDU-6656 题解: 维护一个前缀sum[i] : 从1到 i 的期望 第 i 到达 i + 1是:ai + (1 - r[i] / ...

  10. 2019杭电多校第七场 HDU - 6656 Kejin Player——概率期望

    题意 总共有 $n$ 层楼,在第 $i$ 层花费 $a_i$ 的代价,有 $pi$ 的概率到 $i+1$ 层,否则到 $x_i$($x_i \leq 1$) 层.接下来有 $q$ 次询问,每次询问 $ ...

最新文章

  1. 【RPC服务器不可用】解决方法
  2. 一些有用的ABAP程序和函数组
  3. 第一章:Flask安装
  4. 苹果MacOS系统上安装第三方驱动失败/无效
  5. SQLserver数据库反编译生成Hibernate实体类和映射文件
  6. php周日,PHP减去一周周日
  7. 中国正在发生或可能发生的变化,将影响未来
  8. 2月6日 KNN和Bayes和决策树学习总结
  9. onlyoffice开发java_OnlyOffice功能及演示
  10. 惠普暗影2 pro ubuntu16.04安装nvidia显卡驱动
  11. 基于SSM java学校教务管理系统
  12. 怎么判断一篇微信公众号文章阅读量是不是刷上来的?
  13. 深度学习英文缩写_深度学习相关专业词汇简称汇总
  14. 在天堂与地狱之间——清华浪子梦断中关村 (转)
  15. 【前端】js实现图片自适应
  16. TreeView使用笔记
  17. 程序员代码表白 爱你三千遍
  18. 不管过去如何,未来我们都要奋力前行!
  19. VSCode中设置大小写转换的快捷键
  20. python cx_oracle 取回数据后 LOB variable no longer valid after subsequent fetch

热门文章

  1. 【java与移动智能设备】布局方式
  2. java队列类_用Java编写一个队列类
  3. maria安装包mysql_Redhat 7.3安装系统自带Mariadb安装包
  4. 监控mysql连接池信息_druid-带监控功能的数据库连接池
  5. gin上传文件服务器,gin-上传文件
  6. vue中a标签跳转问题(跳转网址自动加上http://local:8080/)
  7. C# Dictionary 的几种遍历方法
  8. 敏捷开发案例:用白板解决项目管理和团队沟通
  9. XHTML 和 DOCTYPE 切换(MSDN)
  10. 解决AJAX中使用UpdatePanel后再用Response.Write();等无法弹出对话框问题 3法