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

浙公网安备 33010602011771号