HDU第五マルチスクール1002 3つの配列 - 01トライ|安定結婚と第九のフィールド1008リッカイン

HDU第マルチ学校1002年3つのアレイ

トピックリンク:ポイント私はああ╭(╯^╰)╮

効果の件名:

    2つの配列は、任意の位置に変更することができ
    、同じ位置を求めた後、生成した辞書順最小のシーケンスをXOR

問題解決のアイデア:

    2つの組み込み 01 01 の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);
	}
}
公開された221元の記事 ウォンの賞賛220 ・は 20000 +を見て

おすすめ

転載: blog.csdn.net/Scar_Halo/article/details/102990441