codeforces 1446C - Xor Tree (Trie + dfs)
阿新 • • 發佈:2020-12-04
題目連結:https://codeforces.com/problemset/problem/1446/C
還是想不到。。
將所有的數都插入到 \(trie\) 中,根據異或的性質,同一位相同的數,異或起來肯定更小,
所以在 \(trie\) 中,子樹內的數字在建好的圖中一定在同一個連通塊裡,
我們設該位在 \(trie\) 中兩棵子樹的大小分別為 \(S_0, S_1\), 可以發現,如果 \(S < 2\) , 那麼肯定這個節點會在另一個集合的連通塊中,
如果 \(S > 2\),那就要將 \(S\) 減為 \(1\), 使其可以聯通到另一個集合的連通塊中,
所以問題就轉化成了:在 \(trie\)
#include<iostream> #include<algorithm> #include<cstring> #include<cstdio> #include<cmath> using namespace std; typedef long long ll; const int maxn = 200010; int n, rt = 0, tot = 0; int a[maxn]; struct Trie{ int son[2]; int sz; }t[maxn * 32]; void insert(int x){ int p = rt; for(int i = 30; i >= 0 ; --i){ int c = (x >> i) & 1; if(!t[p].son[c]) t[p].son[c] = ++tot; p = t[p].son[c]; t[p].sz += 1; // printf("%d ", p); } //printf("\n"); t[p].sz = 1; } int ans = 0; int sz[maxn * 30]; void dfs(int u, int sum){ // printf("%d %d\n", u, sum); if(!t[u].son[0]){ if(t[u].son[1]) dfs(t[u].son[1], sum); else ans = max(ans, sum + 1); } else if(!t[u].son[1]){ if(t[u].son[0]) dfs(t[u].son[0], sum); else ans = max(ans, sum + 1); } else{ dfs(t[u].son[0], sum + 1); dfs(t[u].son[1], sum + 1); } // ans = max(ans , sum); } ll read(){ ll s = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9'){ if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9'){ s = s * 10 + ch - '0'; ch = getchar(); } return s * f; } int main(){ n = read(); for(int i = 1 ; i <= n ; ++i) { a[i] = read(); insert(a[i]); } dfs(rt, 0); printf("%d\n", n - ans); return 0; }