不知道为啥只开int会炸。。这题思维过程还是很有趣(痛苦)的
/* 01字典树求X异或最大值的策略就是X取反后去字典树里跑,跑到不能跑了就是答案 X在往01trie下搜时,如果碰到要去的地方是null,那么它只能朝另一个方向走, 同时最终异或起来的答案(即和X异或最大的那个值)损失了1<<(29-i) 本题就是要让这个损失的值达到最大 */ #include<bits/stdc++.h> using namespace std; #define ll long long #define N 200005 #define ll long long ll n,a[N]; //root=0 struct Trie{ ll nxt[N*32][2],L,root,pow[N*32],sum[N*32],id[N*32]; int newnode(){ nxt[L][0]=nxt[L][1]=-1; return L++; } inline void init(){ L=0; root=newnode(); pow[root]=1<<29; } void insert(int x,int idx){ int now=root; for(int i=29;i>=0;i--){ int k=(x>>i) & 1; if(nxt[now][k]==-1) nxt[now][k]=newnode(); now=nxt[now][k]; } id[now]=idx; } void solve(){ queue<int>q;q.push(root); while(q.size()){ int now=q.front();q.pop(); for(int i=0;i<2;i++) if(nxt[now][i]!=-1){ pow[nxt[now][i]]=pow[now]/2; q.push(nxt[now][i]); } } q.push(root); while(q.size()){ int now=q.front();q.pop(); int flag=(nxt[now][0]!=-1) && (nxt[now][1]!=-1); for(int i=0;i<2;i++) if(nxt[now][i]!=-1){ sum[nxt[now][i]]=sum[now]; if(flag) sum[nxt[now][i]]+=pow[now]; q.push(nxt[now][i]); } } ll Min=0x3f3f3f3f3f3f3f3f; for(int i=0;i<L;i++) if(id[i]) Min=min(Min,sum[i]); cout<<Min<<' '; } }tr; int main(){ cin>>n; tr.init(); for(int i=1;i<=n;i++){ cin>>a[i]; tr.insert(a[i],i); } tr.solve(); }