题解 CF1446C 【Xor Tree】

xukuan

2020-11-23 21:57:12

Solution

根据套路,这种题应该用字典树来做 满足的条件是存在且只存在一对$(i,j)$,$a_i \space xor \space a_j$的值对双方都是最小的 那么询问的时候, $$ query(p)=\begin{aligned} 1,lson_p=empty,rson_p=empty\\ query(lson_p),lson_p \neq empty,rson_p=empty\\ query(rson_p),lson_p=empty,rson_p \neq empty\\ max(query(lson_p),query(rson_p))+1,lson_p \neq empty,rson_p \neq empty\\ \end{aligned} $$ 前三个柿子都不解释,就解释最后一个 我们假设有两个集合:lson和rson,最小的结果就是一个的最优解加上另外里面选1个,这样另外集合xor剩下的当前为都是1,所以一定不影响结果 代码: ```cpp #include<bits/stdc++.h> #include<iostream> #include<cstdio> #define ll long long using namespace std; const ll N=200010; ll n,cnt=1,tree[N*20][2],root=1; inline ll read(){ ll x=0,tmp=1; char ch=getchar(); while(!isdigit(ch)){ if(ch=='-') tmp=-1; ch=getchar(); } while(isdigit(ch)){ x=(x<<3)+(x<<1)+(ch^48); ch=getchar(); } return tmp*x; } inline void Insert(ll val){ ll p=root; for(ll i=30; i>=0; i--){ ll x=(val>>i)&1; if(!tree[p][x]) tree[p][x]=++cnt; p=tree[p][x]; } } ll query(ll p){ if(!tree[p][0]&&!tree[p][1]) return 1; if(!tree[p][0]) return query(tree[p][1]); if(!tree[p][1]) return query(tree[p][0]); return max(query(tree[p][0]),query(tree[p][1]))+1; } int main(){ n=read(); for(ll i=1; i<=n; i++) Insert(read()); cout<<n-query(root)<<endl; return 0; } ```