题意:

给你两个序列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排序一遍,就不用计较此点最优解是先构造出来的还是后构造出来的了。

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
//const int MAXN=1<<30;
struct Node{
int to[];
bool end;
int size;
};
int c[];
struct Trie{
Node node[*];
int nodenum;
void init(int n){
for(int i=;i<=n*;i++)memset(&node[i],,sizeof (Node));
nodenum=;
}
void push(int n){
int nowid=;
for(int i=;i>=;i--){
++node[nowid].size;
bool t=(n>>i)&;
if(node[nowid].to[t]==){
node[nowid].to[t]=++nodenum;
nowid=nodenum;
}else{
nowid=node[nowid].to[t];
}
// n>>=1;
}
++node[nowid].size;
node[nowid].end=;
}
}trie1,trie2;
int find1(){
int id1=,id2=;
int ans=;
int i=;
bool to10,to11,to20,to21;
while(!trie1.node[id1].end && !trie2.node[id2].end){
ans<<=;
--trie1.node[id1].size;
--trie2.node[id2].size;
to10=trie1.node[trie1.node[id1].to[]].size>;
to11=trie1.node[trie1.node[id1].to[]].size>;
to20=trie2.node[trie2.node[id2].to[]].size>;
to21=trie2.node[trie2.node[id2].to[]].size>;
if(to11 && to21){
id1=trie1.node[id1].to[];
id2=trie2.node[id2].to[];
}else if(to10 && to20){
id1=trie1.node[id1].to[];
id2=trie2.node[id2].to[];
}else if(to10 && to21){
id1=trie1.node[id1].to[];
id2=trie2.node[id2].to[];
++ans;
}else if(to11 && to20){
id1=trie1.node[id1].to[];
id2=trie2.node[id2].to[];
++ans;
}
++i;
}
--trie1.node[id1].size;
--trie2.node[id2].size;
return ans;
}
int main(){
int t;
scanf("%d",&t);
while(t--){
int n,tmp;
scanf("%d",&n);
trie1.init(n);trie2.init(n);
for(int i=;i<=n;i++){
scanf("%d",&tmp);
trie1.push(tmp);
}
for(int i=;i<=n;i++){
scanf("%d",&tmp);
trie2.push(tmp);
}
// for(int i=1;i<=trie1.nodenum;i++){
// printf("%d %d %d %d\n",trie1.node[i].size,trie1.node[i].to[0],trie1.node[i].to[1],trie1.node[i].end);
// }
for(int i=;i<=n;i++){
c[i]=find1();
}
sort(c+,c++n);
for(int i=;i<=n;i++){
printf("%d",c[i]);
if(i<n)printf(" ");
else printf("\n");
}
}
}

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中使用axios进行http通信

    1.安装 npm install axios 2.在main.js中全局注册 // axios不可以通过use引入,可以通过修改vue原型链 import axios from 'axios' Vue ...

  2. delphi 下载

    获取网络文件大小 //delphi 获取网络文件大小 function GetUrlFileSize(aURL: string): integer; var FileSize: integer; va ...

  3. mongodb副本集的内部机制(借鉴lanceyan.com)

    针对mongodb的内部机制提出以下几个引导性的问题: 副本集故障转移,主节点是如何选举的?能否手动干涉下架某一台主节点. 官方说副本集数量最好是奇数,为什么? mongodb副本集是如何同步的?如果 ...

  4. Golang(Go语言)内置函数之copy用法

    该函数主要是切片(slice)的拷贝,不支持数组 将第二个slice里的元素拷贝到第一个slice里,拷贝的长度为两个slice中长度较小的长度值 示例: s := []int{1,2,3} fmt. ...

  5. HIve分组查询返回每组的一条记录

    select a.lng,a.lat from (select row_number() over ( partition by uid,grid_id) as rnum,weighted_centr ...

  6. java连连看小项目

    /* *本人也是刚入门,希望各位多多指教 *该项目主要代码在于连线 *1.2个连线没有拐弯 *2.2个连线有一个拐弯 *3.2个连线有2个拐弯 *采用递归算法 */ package llk; impo ...

  7. CSS Sprite初探之原理、使用

    CSS Sprite简介: 利用CSS Sprites能很好地减少了网页的http请求次数,从而大大的提高了页面的性能,节省时间和带宽.CSS Sprites在国内很多人叫css精灵, 是一种网页图片 ...

  8. VIM编辑器进阶配置

    vim自定义设置        可以选择需要的功能添加至 ~/.vimrc 打开注释使之生效. " 让 vim 关闭所有扩展的功能,尽量模拟 vi 的行为. set nocompatible ...

  9. (Struts2学习系列五)Struts2默认action

    当我们访问项目下一个不存在的Action的时候,页面就会报错,404找不到资源,这样对用户来说是非常不友好的,所以我们设置一个默认的Action,当找不到对应Action的时候,就会跳转到默认Acti ...

  10. Shell 编程综合案例

    Shell编程综合案例 Shell也学习了大概的知识,现在这篇文章就大概讲述下如何使用shell编写一个脚本呢?下面就展示一个大家常用的数据库备份案例来进行展示. 需求分析 1)每天凌晨2:10分备份 ...