【資料結構】01Trie
阿新 • • 發佈:2020-11-20
https://codeforces.ml/contest/888/problem/G
struct TrieNode { int cnt; int num; int nxt[2]; void Init() { cnt = 0; num = 0; memset(nxt, 0, sizeof(nxt)); } }; struct Trie { static const int MAXN = 200000; TrieNode tn[MAXN * 32 + 5]; int root, top; int NewNode() { tn[++top].Init(); return top; } void Init() { top = 0; root = NewNode(); } void Insert(int a) { int cur = root; ++tn[cur].cnt; for(int i = 30; i >= 0; --i) { int &nxt = tn[cur].nxt[a >> i & 1]; if(!nxt) nxt = NewNode(); tn[nxt].num = tn[cur].num | (a & (1 << i)); cur = nxt; ++tn[cur].cnt; } } ll help(int cur, int Rnum) { if(tn[cur].nxt[0] == 0 && tn[cur].nxt[1] == 0) return tn[cur].num ^ Rnum; if(tn[cur].nxt[0] == 0) return help(tn[cur].nxt[1], Rnum); if(tn[cur].nxt[1] == 0) return help(tn[cur].nxt[0], Rnum); if((tn[tn[cur].nxt[0]].num ^ Rnum) < (tn[tn[cur].nxt[1]].num ^ Rnum)) return help(tn[cur].nxt[0], Rnum); else return help(tn[cur].nxt[1], Rnum); } ll count(int cur, int Lroot) { if(tn[cur].nxt[0] == 0 && tn[cur].nxt[1] == 0) return help(Lroot, tn[cur].num); if(tn[cur].nxt[0] == 0) return count(tn[cur].nxt[1], Lroot); if(tn[cur].nxt[1] == 0) return count(tn[cur].nxt[0], Lroot); return min(count(tn[cur].nxt[1], Lroot), count(tn[cur].nxt[0], Lroot)); } ll calc(int cur) { if(cur == 0 || tn[cur].cnt <= 1) return 0; if(tn[cur].nxt[0] == 0 && tn[cur].nxt[1] == 0) return 0; if(tn[cur].nxt[0] == 0) return calc(tn[cur].nxt[1]); if(tn[cur].nxt[1] == 0) return calc(tn[cur].nxt[0]); ll res = calc(tn[cur].nxt[0]) + calc(tn[cur].nxt[1]); ll tmp = count(tn[cur].nxt[1], tn[cur].nxt[0]); return res + tmp; } } trie;