three arrays
Time Limit: 3000/2500 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 2175 Accepted Submission(s): 754
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
Source
2019 Multi-University Training Contest 5
Recommend
liuyiding | We have carefully selected several similar problems for you: 6730 6729 6728 6727 6726
题目大意:两个数组a,b b数组可以重新排序,c数组是有ai^bi 得到的,求如何排列是c的字典序最小。
解题思路:比赛时想到了字典树,直接把b排序了,然后对于每一个b在a中找最小。然而这样是不对的。
正解应该是 建立两颗01字典树,我们尽量走 (0,0) (1,1)因为这样才能使得贡献最小,否则的话就只能
走(0,1) (1,0)。然后将取出来的数字排序就可以了。
#include<bits/stdc++.h>
using namespace std;
#define sca(x) scanf("%d",&x)
#define LL long long
#define pb(x) push_back(x)
const int N = 1e5+5;
struct node
{
int nt[2];
int sz[2];
}t[N*40][2];
int a[N],b[N];
int c[N];
int root;
int tot1,tot2;
void init( )
{
for(int i=0;i<max(tot1,tot2);i++)
{
t[i][0].nt[0]=t[i][0].nt[1]=0;
t[i][0].sz[0]=t[i][0].sz[1]=0;
t[i][1].nt[0]=t[i][1].nt[1]=0;
t[i][1].sz[0]=t[i][1].sz[1]=0;
}
}
int _newnode(int ty)
{
if(ty==0)tot1++;
else tot2++;
int tot=(ty==0?tot1:tot2);
t[tot][ty].nt[0]=t[tot][ty].nt[1]=0;
t[tot][ty].sz[0]=t[tot][ty].sz[1]=0;
return tot;
}
void _ins(int k,int ty)
{
int now=root;
for(int i=30;i>=0;i--){
int id=(k>>i)&1;
if(t[now][ty].nt[id]==0){
t[now][ty].nt[id] = _newnode(ty);
}
t[now][ty].sz[id]++;
now=t[now][ty].nt[id];
}
}
int _ask( )
{
int le=0,ri=0;
int res=0;
for(int i=30;i>=0;i--)
{
int s10=t[le][0].sz[0],s11=t[le][0].sz[1];
int s20=t[ri][1].sz[0],s21=t[ri][1].sz[1];
if(s10 && s20)
{
t[le][0].sz[0]--;
t[ri][1].sz[0]--;
le=t[le][0].nt[0];
ri=t[ri][1].nt[0];
continue;
}
if(s11 && s21)
{
t[le][0].sz[1]--;
t[ri][1].sz[1]--;
le=t[le][0].nt[1];
ri=t[ri][1].nt[1];
continue;
}
if(s10 && s21)
{
t[le][0].sz[0]--;
t[ri][1].sz[1]--;
res|= (1<<i);
le=t[le][0].nt[0];
ri=t[ri][1].nt[1];
continue;
}
if(s11 && s20 )
{
t[le][0].sz[1]--;
t[ri][1].sz[0]--;
res|=(1<<i);
le=t[le][0].nt[1];
ri=t[ri][1].nt[0];
continue;
}
}
return res;
}
int main()
{
int t;
cin>>t;
while(t--)
{
tot1=tot2=0;
root=0;
int n;
sca(n);
for(int i=1;i<=n;i++){
sca(a[i]);
}
for(int i=1;i<=n;i++){
sca(b[i]);
}
for(int i=1;i<=n;i++){
_ins(a[i],0);
_ins(b[i],1);
}
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]);
if(i==n)printf("\n");
else printf(" ");
}
init( );
}
}