Problem Description
There are three integer arrays a,b,c. The lengths of them are all N. You are given the full contents of a and b. And the elements in c is produced by following equation: c[i]=a[i] XOR b[i] where XOR is the bitwise exclusive or operation.
Now you can rearrange the order of elements in arrays a and b independently before generating the array c. We ask you to produce the lexicographically smallest possible array c after reordering a and b. Please output the resulting array c.
Input
The first line contains an integer T indicating there are T tests.
Each test consists of three lines. The first line contains one positive integer N denoting the length of arrays a,b,c. The second line describes the array a. The third line describes the array b.
-
T≤1000
-
1≤N≤105
-
integers in arrays a and b are in the range of [0,230).
-
at most 6 tests with N>100
Output
For each test, output a line containing N integers, representing the lexicographically smallest resulting array c.
Sample Input
1
3
3 2 1
4 5 6
Sample Output
4 4 7
题意:
给两个长度为n的数组a,b
告诉你c(i)=a(i)^b(i)
现在要你重新排列a,b数组,
要求c数组的字典序最小
输出c数组的每个元素值
分析:
不必真的重新排列a、b数组
只要能求出c数组就行了
为两个数组建立两棵01字典树
对于每个i,从两颗树的树顶开始跑,
优先走数值相同的路径(0,0或者1,1)
如果没有就只能走不同的(0,1或者1,0)
就能得到一个值c(i)
求出所有c的值之后排序一下保证字典序最小然后输出即可
具体看代码
如果用memset初始化会tle
ps:
好题啊,学到了新的代码格式,新的初始化方法,trie的新操作
code:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxm=1e5+5;
struct Trie{
int a[maxm*30][2],tot;
int cnt[maxm*30];
void init(){
for(int i=1;i<tot;i++){//只把用过的清零
a[i][0]=a[i][1]=0;
cnt[i]=0;
}
tot=1;
}
void add(int x){
int node=0;
for(int i=30;i>=0;i--){
int v=(x>>i&1);
if(!a[node][v]){
a[node][v]=tot++;
}
node=a[node][v];
cnt[node]++;//路径经过的次数
}
}
}a,b;
int c[maxm];
int ask(){
int ans=0;
int pa=0,pb=0;
for(int i=30;i>=0;i--){
if(a.cnt[a.a[pa][0]]&&b.cnt[b.a[pb][0]]){//0,0
a.cnt[a.a[pa][0]]--;
b.cnt[b.a[pb][0]]--;
pa=a.a[pa][0];
pb=b.a[pb][0];
}else if(a.cnt[a.a[pa][1]]&&b.cnt[b.a[pb][1]]){//1,1
a.cnt[a.a[pa][1]]--;
b.cnt[b.a[pb][1]]--;
pa=a.a[pa][1];
pb=b.a[pb][1];
}else if(a.cnt[a.a[pa][0]]&&b.cnt[b.a[pb][1]]){//0,1
a.cnt[a.a[pa][0]]--;
b.cnt[b.a[pb][1]]--;
pa=a.a[pa][0];
pb=b.a[pb][1];
ans+=(1<<i);
}else if(a.cnt[a.a[pa][1]]&&b.cnt[b.a[pb][0]]){//1,0
a.cnt[a.a[pa][1]]--;
b.cnt[b.a[pb][0]]--;
pa=a.a[pa][1];
pb=b.a[pb][0];
ans+=(1<<i);
}
}
return ans;
}
int main(){
int T;
scanf("%d",&T);
while(T--){
a.init();//reset
b.init();//reset
int n;
scanf("%d",&n);
for(int i=1,x;i<=n;i++){
scanf("%d",&x);
a.add(x);
}
for(int i=1,x;i<=n;i++){
scanf("%d",&x);
b.add(x);
}
for(int i=1;i<=n;i++){
c[i]=ask();
}
sort(c+1,c+1+n);
for(int i=1;i<n;i++){
printf("%d ",c[i]);
}
printf("%d\n",c[n]);
}
return 0;
}
来源:https://blog.csdn.net/weixin_44178736/article/details/100669051