HDU多校第五场 1002 three arrays
题目链接:点我啊╭(╯^╰)╮
题目大意:
两个序列,可以任意调换位置
求相同位置异或后产生的字典序最小序列
解题思路:
建两颗
字典树,然后同时 DFS
优先走相同边,然后走不同边
最后得到的答案排序后就是最小序列
核心:01字典树 dfs
#include<bits/stdc++.h>
#define rint register int
#define deb(x) cerr<<#x<<" = "<<(x)<<'\n';
using namespace std;
typedef unsigned long long ll;
typedef pair <int,int> pii;
const int maxn = 1e5 + 10;
int T, n;
vector <pii> ans;
struct Trie{
static const int maxt = 1e7+5;
int rt, id, tot, t[maxt][2];
int cnt[maxt], val[maxt], end[maxt];
inline int newnode(){
++tot;
t[tot][0] = t[tot][1] = 0;
cnt[tot] = end[tot] = val[tot] = 0;
return tot;
}
inline void init(){
tot = 0;
rt = newnode();
}
inline void add(int x){
rt = 1;
for(int i=31; ~i; i--){
id = x >> i & 1;
if(!t[rt][id]) t[rt][id] = newnode();
rt = t[rt][id];
++cnt[rt];
}
end[rt] = 1, val[rt] = x;
}
inline int query(int x){
rt = 1;
for(int i=31; ~i; i--){
id = x >> i & 1;
if(t[rt][id^1]) rt = t[rt][id^1];
else rt = t[rt][id];
}
return x ^ val[rt];
}
} A, B;
void dfs(int p1, int p2, int x){
int num = min(A.cnt[p1], B.cnt[p2]);
A.cnt[p1] -= num, B.cnt[p2] -= num;
if(A.end[p1]){
ans.push_back({x, num});
return ;
}
if(A.cnt[A.t[p1][0]] && B.cnt[B.t[p2][0]])
dfs(A.t[p1][0], B.t[p2][0], x<<1);
if(A.cnt[A.t[p1][1]] && B.cnt[B.t[p2][1]])
dfs(A.t[p1][1], B.t[p2][1], x<<1);
if(A.cnt[A.t[p1][0]] && B.cnt[B.t[p2][1]])
dfs(A.t[p1][0], B.t[p2][1], x<<1|1);
if(A.cnt[A.t[p1][1]] && B.cnt[B.t[p2][0]])
dfs(A.t[p1][1], B.t[p2][0], x<<1|1);
}
int main() {
scanf("%d", &T);
while(T--){
scanf("%d", &n);
ans.clear();
A.init(), B.init();
for(int i=0, tmp; i<n; i++){
scanf("%d", &tmp);
A.add(tmp);
}
for(int i=0, tmp; i<n; i++){
scanf("%d", &tmp);
B.add(tmp);
}
dfs(1, 1, 0);
sort(ans.begin(), ans.end());
for(int i=0; i<ans.size(); i++)
for(int j=0; j<ans[i].second; j++){
printf("%d", ans[i].first);
printf("%c", i==ans.size()-1&&j==ans[i].second-1 ? '\n' : ' ');
}
}
}
第九场 1008 Rikka with Stable Marriage
题目链接:点我啊╭(╯^╰)╮
题目大意:
两个序列,可以任意调换位置
求相同位置异或后产生的字典序最大序列
#include<bits/stdc++.h>
#define rint register int
#define deb(x) cerr<<#x<<" = "<<(x)<<'\n';
using namespace std;
typedef long long ll;
using pii = pair <int,int>;
int T, n;
ll ans;
struct Trie{
static const int maxt = 1e7 + 5;
int rt, id, tot, t[maxt][2];
int cnt[maxt], val[maxt], end[maxt];
int newnode(){
t[++tot][0] = t[tot][1] = 0;
cnt[tot] = end[tot] = val[tot] = 0;
return tot;
}
void init(){
tot = 0;
rt = newnode();
}
void add(int x){
rt = 1;
for(int i=31; ~i; i--){
id = x >> i & 1;
if(!t[rt][id]) t[rt][id] = newnode();
rt = t[rt][id];
++cnt[rt];
}
end[rt] = 1, val[rt] = x;
}
} A, B;
void dfs(int p1, int p2, int x){
int num = min(A.cnt[p1], B.cnt[p2]);
A.cnt[p1] -= num, B.cnt[p2] -= num;
if(A.end[p1]){
ans += A.val[p1] ^ B.val[p2];
return;
}
if(A.cnt[ A.t[p1][0] ] && B.cnt[ B.t[p2][1] ])
dfs(A.t[p1][0], B.t[p2][1], x<<1);
if(A.cnt[ A.t[p1][1] ] && B.cnt[ B.t[p2][0] ])
dfs(A.t[p1][1], B.t[p2][0], x<<1);
if(A.cnt[ A.t[p1][0] ] && B.cnt[ B.t[p2][0] ])
dfs(A.t[p1][0], B.t[p2][0], x<<1);
if(A.cnt[ A.t[p1][1] ] && B.cnt[ B.t[p2][1] ])
dfs(A.t[p1][1], B.t[p2][1], x<<1);
}
int main() {
scanf("%d", &T);
while(T--){
A.init(), B.init();
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);
ans = 0;
dfs(1, 1, 0);
printf("%lld\n", ans);
}
}