题意:

给你两个序列a,b,序列c的某位是由序列a,b的此位异或得来,让你重排序列ab,找出字典序最小的序列c。

题解:

如果能找到a,b序列中完全一样的值当然最好,要是找不到,那也尽量让低位不一样。

因此,将两个序列中元素的二进制视作字符串,建字典树。

在两棵字典树上,贪心地找让当前位一样的。

每找c的一位,dfs一遍,dfs过程中剪掉已经因为构造c而用掉的子树,构造序列c。

然后爆wa。。。

我造了好几组测例,发现贪心并不能找出当前位的最优解,比如dfs到两棵字典树上的某个点,这两个节点都既有左儿子,又有右儿子,那么到底是都向左走更优,还是都向右走更优,字典树上没有这个信息。

比如数据  3  1,0,2  2,4,1  程序打死都要给出我0,4,0的结果

直到有人提醒我:“你再把c数组排个序不就行了嘛”

我:“。。。。。。”

那么,不管不顾地贪心,只要dfs到的两点都能向1的方向走,那就都向1的方向走,因为当都向1这个方向走这棵子树此次被剪掉后,以后一定能构造出都向0的方向走的最优解。

只要再把c排序一遍,就不用计较此点最优解是先构造出来的还是后构造出来的了。

  1. #include<iostream>
  2. #include<cstring>
  3. #include<algorithm>
  4. using namespace std;
  5. //const int MAXN=1<<30;
  6. struct Node{
  7. int to[];
  8. bool end;
  9. int size;
  10. };
  11. int c[];
  12. struct Trie{
  13. Node node[*];
  14. int nodenum;
  15. void init(int n){
  16. for(int i=;i<=n*;i++)memset(&node[i],,sizeof (Node));
  17. nodenum=;
  18. }
  19. void push(int n){
  20. int nowid=;
  21. for(int i=;i>=;i--){
  22. ++node[nowid].size;
  23. bool t=(n>>i)&;
  24. if(node[nowid].to[t]==){
  25. node[nowid].to[t]=++nodenum;
  26. nowid=nodenum;
  27. }else{
  28. nowid=node[nowid].to[t];
  29. }
  30. // n>>=1;
  31. }
  32. ++node[nowid].size;
  33. node[nowid].end=;
  34. }
  35. }trie1,trie2;
  36. int find1(){
  37. int id1=,id2=;
  38. int ans=;
  39. int i=;
  40. bool to10,to11,to20,to21;
  41. while(!trie1.node[id1].end && !trie2.node[id2].end){
  42. ans<<=;
  43. --trie1.node[id1].size;
  44. --trie2.node[id2].size;
  45. to10=trie1.node[trie1.node[id1].to[]].size>;
  46. to11=trie1.node[trie1.node[id1].to[]].size>;
  47. to20=trie2.node[trie2.node[id2].to[]].size>;
  48. to21=trie2.node[trie2.node[id2].to[]].size>;
  49. if(to11 && to21){
  50. id1=trie1.node[id1].to[];
  51. id2=trie2.node[id2].to[];
  52. }else if(to10 && to20){
  53. id1=trie1.node[id1].to[];
  54. id2=trie2.node[id2].to[];
  55. }else if(to10 && to21){
  56. id1=trie1.node[id1].to[];
  57. id2=trie2.node[id2].to[];
  58. ++ans;
  59. }else if(to11 && to20){
  60. id1=trie1.node[id1].to[];
  61. id2=trie2.node[id2].to[];
  62. ++ans;
  63. }
  64. ++i;
  65. }
  66. --trie1.node[id1].size;
  67. --trie2.node[id2].size;
  68. return ans;
  69. }
  70. int main(){
  71. int t;
  72. scanf("%d",&t);
  73. while(t--){
  74. int n,tmp;
  75. scanf("%d",&n);
  76. trie1.init(n);trie2.init(n);
  77. for(int i=;i<=n;i++){
  78. scanf("%d",&tmp);
  79. trie1.push(tmp);
  80. }
  81. for(int i=;i<=n;i++){
  82. scanf("%d",&tmp);
  83. trie2.push(tmp);
  84. }
  85. // for(int i=1;i<=trie1.nodenum;i++){
  86. // printf("%d %d %d %d\n",trie1.node[i].size,trie1.node[i].to[0],trie1.node[i].to[1],trie1.node[i].end);
  87. // }
  88. for(int i=;i<=n;i++){
  89. c[i]=find1();
  90. }
  91. sort(c+,c++n);
  92. for(int i=;i<=n;i++){
  93. printf("%d",c[i]);
  94. if(i<n)printf(" ");
  95. else printf("\n");
  96. }
  97. }
  98. }

hdu多校第五场1002 (hdu6625) three arrays 字典树/dfs的更多相关文章

  1. hdu多校第五场1005 (hdu6628) permutation 1 排列/康托展开/暴力

    题意: 定义一个排列的差分为后一项减前一项之差构成的数列,求对于n个数的排列,差分的字典序第k小的那个,n<=20,k<=1e4. 题解: 暴力打表找一遍规律,会发现,对于n个数的排列,如 ...

  2. 2014 HDU多校弟五场J题 【矩阵乘积】

    题意很简单,就是两个大矩阵相乘,然后求乘积. 用 Strassen算法 的话,当N的规模达到100左右就会StackOverFlow了 况且输入的数据范围可达到800,如果变量还不用全局变量的话连内存 ...

  3. 2014 HDU多校弟五场A题 【归并排序求逆序对】

    这题是2Y,第一次WA贡献给了没有long long 的答案QAQ 题意不难理解,解题方法不难. 先用归并排序求出原串中逆序对的个数然后拿来减去k即可,如果答案小于0,则取0 学习了归并排序求逆序对的 ...

  4. 2018杭电多校第五场1002(暴力DFS【数位】,剪枝)

    //never use translation#include<bits/stdc++.h>using namespace std;int k;char a[20];//储存每个数的数值i ...

  5. hdu多校第五场1004 (hdu6627) equation 1 计算几何

    题意: 给你一个C,再给你n组a,b,让你求x取什么值的时候,$ \sum_{i=1}^n |a_i*x+b_i| =C $,要求求出解的个数,并用最简分数从小到大表示,如果有无穷多解,输出-1. 题 ...

  6. hdu多校第五场1006 (hdu6629) string matching Ex-KMP

    题意: 给你一个暴力匹配字符串公共前缀后缀的程序,为你对于某个字符串,暴力匹配的次数是多少. 题解: 使用扩展kmp构造extend数组,在扩展kmp中,设原串S和模式串T. extend[i]表示T ...

  7. hdu多校第五场1007 (hdu6630) permutation 2 dp

    题意: 给你n个数,求如下限制条件下的排列数:1,第一位必须是x,2,最后一位必须是y,3,相邻两位之差小于等于2 题解: 如果x<y,那么考虑把整个数列翻转过来,减少讨论分支. 设dp[n]为 ...

  8. hdu多校第4场E. Matrix from Arrays HDU 二维前缀和

    Problem E. Matrix from Arrays Time Limit: / MS (Java/Others) Memory Limit: / K (Java/Others) Total S ...

  9. HDU多校第三场 Hdu6606 Distribution of books 线段树优化DP

    Hdu6606 Distribution of books 题意 把一段连续的数字分成k段,不能有空段且段和段之间不能有间隔,但是可以舍去一部分后缀数字,求\(min(max((\sum ai ))\ ...

随机推荐

  1. Vue开发复用组件的基本思想

    可复用组件的价值在于高复用性,它更能将一个项目往高内聚.低耦合的方向发展. 1.组件命名------按组件功能命名: 2.组件内容------明确组件需要实现什么样的功能: 3.组件体积------越 ...

  2. 「NOI2016」循环之美 解题报告

    「NOI2016」循环之美 对于小数\(\frac{a}{b}\),如果它在\(k\)进制下被统计,需要满足要求并且不重复. 不重复我们确保这个分数是最简分数即\((a,b)=1\) 满足要求需要满足 ...

  3. noip提高组 2010 关押罪犯 (洛谷1525)

    题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用"怨气值"( ...

  4. AcWing 199. 余数之和 (除法分块)打卡

    给出正整数n和k,计算j(n, k)=k mod 1 + k mod 2 + k mod 3 + … + k mod n的值. 例如j(5, 3)=3 mod 1 + 3 mod 2 + 3 mod ...

  5. ios获取软键盘完成事件

    ios获取软键盘完成事件,通过判断input的onBlur事件即可

  6. base64和Xxtea的加密和解密

    base64和Xxtea的加密和解密 数据加密是web数据安全的一种方式,前几天拿到一个base64+xxtea加密的数据,现在在这里整理一下使用的过程.首先当然是全网站找解密方法,但是最后的结果不是 ...

  7. 16、使用jQuery的html5player播放器,进行播放

    <!-- Website Design By: www.happyworm.com --> <title>Demo : jPlayer as a video playlist ...

  8. [转] bae中thinkphp的REWRITE 正确配置方法

    URL_MODEL =2下. 官方的:app.conf不能用,害人呀.. 留意以下红色部分,正则要分开来写,坑爹的 正确的配置: handlers: handlers: - expire : .jpg ...

  9. 词表征 1:WordNet、0-1表征、共现矩阵、SVD

    原文地址:https://www.jianshu.com/p/c1e4f42b78d7 一.基于知识的表征 参见图1.1,WordNet中包含同义词集(synonym sets)和上位词(hypern ...

  10. nrm的安装使用

    1.利用npm来安装nrm,且是全局安装nrm包 npm i nrm -g 2.使用nrm ls查看当前所有可用的镜像源地址以及当前所使用的镜像源地址 3.使用nrm use npm 或者nrm us ...