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; }