一.题目链接:

HDU-6625

二.题目大意:

给两个长度为 n 的数组 a,b.

定义 c = a ^ b.

先让你变换 a,b 中元素的顺序,使得 c 的字典序最小.

三.分析:

看到第一眼就想到字典树了,可是有些地方不会写......

赛后发现其实不难,本质与这道题一样,就是麻烦了点.

我好菜啊..............

ps:用 memset TLE,必须边建树边初始化.

四.代码实现:

#include <set>
#include <map>
#include <ctime>
#include <queue>
#include <cmath>
#include <stack>
#include <bitset>
#include <vector>
#include <cstdio>
#include <sstream>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define eps 1e-8
#define lc k * 2
#define rc k * 2 + 1
#define pi acos(-1.0)
#define ll long long
#define ull unsigned long long
using namespace std;

const int M = (int)1e5;
const int mod = 99991;
const int inf = 0x3f3f3f3f;

int x;
int cnt[2];
struct node
{
    int cnt;
    int nx[2];
}trie[2][M * 32 + 5];

int ans[M + 5];

void init()
{
    cnt[0] = cnt[1] = 1;
    trie[0][1].nx[0] = trie[0][1].nx[1] = trie[0][1].cnt = 0;
    trie[1][1].nx[0] = trie[1][1].nx[1] = trie[1][1].cnt = 0;
}

void Insert(int idx, int x)
{
    int p = 1, v;
    for(int i = 29; i >= 0; --i)
    {
        v = (x>>i) & 1;
        if(!trie[idx][p].nx[v])
        {
            trie[idx][p].nx[v] = ++cnt[idx];
            trie[idx][cnt[idx]].nx[0] = trie[idx][cnt[idx]].nx[1] = trie[idx][cnt[idx]].cnt = 0;
        }
        p = trie[idx][p].nx[v];
        trie[idx][p].cnt++;
    }
}

int Query()
{
    int p1 = 1;
    int p2 = 1;
    int res = 0;
    for(int i = 29; i >= 0; --i)
    {
        if(trie[0][trie[0][p1].nx[0]].cnt && trie[1][trie[1][p2].nx[0]].cnt)
        {
            p1 = trie[0][p1].nx[0];
            p2 = trie[1][p2].nx[0];
            trie[0][p1].cnt--;
            trie[1][p2].cnt--;
        }
        else if(trie[0][trie[0][p1].nx[1]].cnt && trie[1][trie[1][p2].nx[1]].cnt)
        {
            p1 = trie[0][p1].nx[1];
            p2 = trie[1][p2].nx[1];
            trie[0][p1].cnt--;
            trie[1][p2].cnt--;
        }
        else if(trie[0][trie[0][p1].nx[0]].cnt && trie[1][trie[1][p2].nx[1]].cnt)
        {
            p1 = trie[0][p1].nx[0];
            p2 = trie[1][p2].nx[1];
            trie[0][p1].cnt--;
            trie[1][p2].cnt--;
            res |= (1<<i);
        }
        else if(trie[0][trie[0][p1].nx[1]].cnt && trie[1][trie[1][p2].nx[0]].cnt)
        {
            p1 = trie[0][p1].nx[1];
            p2 = trie[1][p2].nx[0];
            trie[0][p1].cnt--;
            trie[1][p2].cnt--;
            res |= (1<<i);
        }
    }
    return res;
}

int main()
{
    int T;
    scanf("%d", &T);
    while(T--)
    {
        init();
        int n;
        scanf("%d", &n);
        for(int i = 0; i < n; ++i)
        {
            scanf("%d", &x);
            Insert(0, x);
        }
        for(int i = 0; i < n; ++i)
        {
            scanf("%d", &x);
            Insert(1, x);
        }
        for(int i = 0; i < n; ++i)
            ans[i] = Query();
        sort(ans, ans + n);
        for(int i = 0; i < n; ++i)
            printf("%d%c", ans[i], i == n - 1 ? '\n' : ' ');
    }
    return 0;
}