The 2020 ICPC Asia Macau Regional Contest C题 (最小异或生成树)

传送门

代码

/*************************************************************************
    > File Name: 1.cpp
    > Author: Knowledge-Pig
    > Mail: 925538513@qq.com
    > Blog: https://www.cnblogs.com/Knowledge-Pig/
    > Created Time: 2021年11月11日 星期四 08时33分20秒
************************************************************************/

#include<bits/stdc++.h>
#define For(i,a,b) for(int i=(a);i<=(b);++i)
#define LL long long
#define pb push_back
#define fi first
#define se second
#define pr pair<int,int>
#define mk(a,b) make_pair(a,b)
#define endl '\n'
#define ine LL
using namespace std;
const int maxx = 3e5 + 10;
int n, a[maxx], f[maxx], color[maxx];
struct node{
	int val, id;
	bool operator <(const node &A) const{
		return val < A.val;
	}
}b[maxx];
struct Trie{
	int cnt, c[maxx * 30][2], l[maxx * 30], r[maxx * 30], ans;
	void init(){ cnt = 1; ans =  (1 << 30); }
	void insert(int x, int id){
		int u  = 1; l[u] = 1; r[u] = id;
		for(int i = (1 << 30); i >= 1; i >>= 1){
			int t = ((x & i) > 0);
			if(!c[u][t]){ c[u][t] = ++cnt; l[cnt] = id; }
			u = c[u][t];
			r[u] = id;
		}
		if(r[u] - l[u] + 1 >= 3) ans = 0;
	}
	void dfs(int id){
		if(r[id] == l[id]) return;
		if(r[id] - l[id] == 1){
			f[r[id]] = (f[l[id]] ^ 1);
			return;
		}
		if(c[id][0]) dfs(c[id][0]);
		if(c[id][1]) dfs(c[id][1]);
		bool flag = (r[c[id][0]] - l[c[id][0]] >= 2) | (r[c[id][1]] - l[c[id][1]] >= 2);
		if(!flag && c[id][0] && c[id][1]){
			int u = c[id][0], v = c[id][1];
			if(l[u] != r[u]) swap(u, v);
			if(l[u] == r[u]){
				if((a[l[u]] ^ a[l[v]]) < (a[l[u]] ^ a[r[v]])){
					f[l[u]] = f[r[v]];
					ans = min(ans, (a[l[u]] ^ a[r[v]]));
				}
				else{
					f[l[u]] = f[l[v]];
					ans = min(ans, (a[l[u]] ^ a[l[v]]));
				}
			}
			else{
				int sol_1 = min(a[l[u]] ^ a[l[v]], a[r[u]] ^ a[r[v]]);
				int sol_2 = min(a[l[u]] ^ a[r[v]], a[r[u]] ^ a[l[v]]);
				if(sol_1 > sol_2){
					f[l[u]] = f[l[v]];
					f[r[u]] = f[r[v]];
					ans = min(ans, sol_1);
				}
				else{
					f[l[u]] = f[r[v]];
					f[r[u]] = f[l[v]];
					ans = min(ans, sol_2);
				}
			}
		}
	}
}trie;	

int main(){
	ios::sync_with_stdio(false); cin.tie(0);
#ifndef ONLINE_JUDGE
	freopen("input.in", "r", stdin);
	freopen("output.out", "w", stdout);
#endif
	int T; cin >> T;
	while(T--){
		cin >> n;
		for(int i = 1; i <= n; ++i){ cin >> b[i].val; f[i] = 0; b[i].id = i; }
		sort(b + 1, b + n + 1);
		trie.init();
		for(int i = 1; i <= n; ++i){
			a[i] = b[i].val;
			trie.insert(a[i], i);
		}
		if(trie.ans) trie.dfs(1);
		cout << trie.ans << endl;
		for(int i = 1; i <= n; ++i){
			color[b[i].id] = f[i] + 1;
		}
		for(int i = 1; i <= n; ++i) cout << color[i];
		cout << endl;
/*
 		int tmp = (1 << 30);
		for(int i = 1; i <= n; ++i) for(int j = i + 1; j <= n; ++j)
			if(f[i] == f[j]) tmp = min(tmp, a[i] ^ a[j]); 
		if(trie.ans != tmp) cout << -1 << endl;
*/
		for(int i = 0; i <= trie.cnt; ++i) trie.l[i] = trie.r[i] = trie.c[i][0] = trie.c[i][1] = 0;
	}
	return 0;
}
posted @ 2021-11-11 17:19  Knowledge-Pig  阅读(33)  评论(0)    收藏  举报