HDU第マルチ学校1002年3つのアレイ
トピックリンク:ポイント私はああ╭(╯^╰)╮
効果の件名:
2つの配列は、任意の位置に変更することができ
、同じ位置を求めた後、生成した辞書順最小のシーケンスをXOR
問題解決のアイデア:
2つの組み込み
の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リッカイン
トピックリンク:ポイント私はああ╭(╯^╰)╮
効果の件名:
2つの配列は、位置を任意に交換することができる
最大の後に生成された辞書式配列が同じ位置を求めるXOR
#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);
}
}