2019杭电暑期多校第五场 B:three arrays(01字典树)

【题解】

题意:给定两个数组a和b,重排数组使得得到的数组c[i]=a[i]^b[i]字典序最小。

题解:对于两个数组从高位到低位建立两个01字典树,然后从高位到低位走,因为要求最小异或值,所以如果下一位两者有相同的就走相同的。最后排一下序输出即可。

前置知识:字典树与01字典树 详解

【代码】

#include 
using namespace std;
const int maxn=1e5+10;
struct node{
	int nex[2];
	int val;
}t[2][maxn*32];
int ans[maxn],pos[3];
void add(int x,int k) //建立01字典树
{
	int p=0;
	for(int i=29;i>=0;i--){
		int op=(1&(x>>i)); //取出第i位
		if(!t[k][p].nex[op]){
			t[k][p].nex[op]=++pos[k];
			t[k][pos[k]].nex[0]=t[k][pos[k]].nex[1]=t[k][pos[k]].val=0;
		}
		p=t[k][p].nex[op];
		t[k][p].val++; //访问次数+1
	}
}
int query()
{
	int p0=0,p1=0; //从根节点开始
	int x=0;
	for(int i=29;i>=0;i--){ //30位逐位查找
		if(t[0][t[0][p0].nex[0]].val&&t[1][t[1][p1].nex[0]].val){
			p0=t[0][p0].nex[0];
			t[0][p0].val--;
			p1=t[1][p1].nex[0];
			t[1][p1].val--;
		}
		else if(t[0][t[0][p0].nex[1]].val&&t[1][t[1][p1].nex[1]].val){
			p0=t[0][p0].nex[1];
			t[0][p0].val--;
			p1=t[1][p1].nex[1];
			t[1][p1].val--;
		} 
		else if(t[0][t[0][p0].nex[1]].val&&t[1][t[1][p1].nex[0]].val){
			p0=t[0][p0].nex[1];
			t[0][p0].val--;
			p1=t[1][p1].nex[0];
			t[1][p1].val--;
			x+=(1<

 

你可能感兴趣的:(2019杭电暑期多校第五场 B:three arrays(01字典树))