three arrays(hdu 6625)

题目链接

男友自动供题机 の 第一题

原本的思路:

  本来是想把a数组按二进制建一个字典树,然后用b数组进行最优匹配,但是自己完全想不到怎么处理重复的问题,思路乱七八糟的 , 如果有dalao这么做的请ddw!

后来:

  在我努(kan)力(wan)学(ti)习(jie)了一会儿后 ,发现是这样的:

    按照二进制给两个数组分别建立a ,b两棵字典树然后每次搜索进行最优的匹配 。

  详细看代码

#include<bits/stdc++.h>
using namespace std;
const int maxn =  3e6 + 10;
#define ios std::ios::sync_with_stdio(false)
struct node
{
    int ci , di[2];///c表示当前点还有多少的使用次数,di存当前位为0和1的下标
};
node treea[maxn] , treeb[maxn];///两棵树
int cnta , cntb;///两棵树的最大下标
void init()///初始化
{
    for(int i = 0 ; i <= cnta ; i ++){
        treea[i].ci = 0;
        treea[i].di[0] = treea[i].di[1] = 0;
    }
    for(int i = 0 ; i <= cntb ; i ++){
        treeb[i].ci = 0;
        treeb[i].di[0] = treeb[i].di[1] = 0;
    }
}
void insert1(int a)
{
    int dir = 1;///初始坐标
    for(int i = 32 ; i >= 0 ; i --){
        int t = (a >> i & 1);
        if(treea[dir].di[t] == 0){///如果当前位为t的还没有生成一个
            treea[dir].di[t] = ++cnta;
        }
        dir = treea[dir].di[t];///换到这个坐标
        treea[dir].ci ++;///使用度+1
    }
}
void insert2(int b)///同上
{
    int dir = 1;
    for(int i = 32 ; i >= 0 ; i --){
        int t = (b >> i & 1);
        if(treeb[dir].di[t] == 0){
            treeb[dir].di[t] = ++cntb;
        }
        dir = treeb[dir].di[t];
        treeb[dir].ci ++;
    }
}
int get_ans()
{
    int ca = 1 , cb = 1;///两个初始坐标
    int ans = 0;
    for(int i = 32 ; i >= 0 ; i --){
        int zeroa = 0 , zerob = 0 , onea = 0 , oneb = 0 ;///当前为01是否有使用度
        if(treea[ca].di[0] != 0 && treea[treea[ca].di[0]].ci > 0)zeroa = 1;
        if(treea[ca].di[1] != 0 && treea[treea[ca].di[1]].ci > 0)onea = 1;
        if(treeb[cb].di[0] != 0 && treeb[treeb[cb].di[0]].ci > 0)zerob = 1;
        if(treeb[cb].di[1] != 0 && treeb[treeb[cb].di[1]].ci > 0)oneb = 1;
        if(onea && oneb){
            ca = treea[ca].di[1];
            cb = treeb[cb].di[1];
        }
        else if(zeroa && zerob){
            ca = treea[ca].di[0];
            cb = treeb[cb].di[0];
        }
        else if(zeroa && oneb){
            ca = treea[ca].di[0];
            cb = treeb[cb].di[1];
            ans += (1 << i);
        }
        else if(zerob && onea){
            ca = treea[ca].di[1];
            cb = treeb[cb].di[0];
            ans += (1 << i);
        }
        treea[ca].ci --;
        treeb[cb].ci --;
    }
    return ans;
}
int a[maxn] , b[maxn] , c[maxn];
signed main()
{
    ios;
    cin.tie(0);///
    int t;
    cin >> t;
    while(t --)
    {
        int n;
        cin >> n;
        cnta = 1;
        cntb = 1;
        for(int i = 1 ; i <= n ; i ++) cin >> a[i] , insert1(a[i]);
        for(int i = 1 ; i <= n ; i ++) cin >> b[i] , insert2(b[i]);
        for(int i = 1 ; i <= n ; i ++){
            c[i] = get_ans();
        }
        sort(c + 1 , c + 1 + n);
        for(int i = 1 ; i <= n ; i ++){
            cout << c[i];
            if(i != n)cout << ' ';
        }
        cout << '\n';
        init();
    }
    return 0;
}
View Code

 

posted @ 2020-04-19 02:49  GoodVv  阅读(179)  评论(1编辑  收藏  举报