CF1285D Dr.イーブルアンダースコア

ハンギングリンク

説明:

あなた\(N \)\(A_1、A_2、......、A_N \)あなたが見つけるように、\(xと\) そう\(X \)が排他的であるか、すべての数が得られた後に(\ N- \)結果の最小値と最大値。

解決:

セット\(Xは、\) タイトルに記載されている(M \)\(a_iを最大{X} ^ \)\

建設\(01Trie \)は、全てに格納されたバイナリ数の形で\(01Trie \)で、最初のための\(K \)ビット、2つのケースがあります。

  • まず、両方とも、0又は1であるように長い\(X \)(K \)\ビットが1または0であり、それが可能であるに\(M \)のk番目のビットが0貪欲な戦略であります高は0数は数1、どんなに低いため、高い歳未満でなければなりません。

  • 第二に、それは大きい方、0と1、次に別のDFSを有しています。この状況はよく理解されていない、あなたは、特定のコードを見ることができます。

コード:

私は構築できませんでした\(トライを\)が、直接、DFS。

\は(DFS(V []、 K)\) を表し\(V \)の最小数(M \)を\、そして第二に見出されている\(K \)のビット。(ショベル黒板には、フォーカスを描きます!


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const ll N = 1e5+1;
ll n,ans;

ll dfs(vector<ll> v,ll k)
{
    vector<ll> v1,v2;
    if(k<0) return 0;
    for(int i=0;i<v.size();++i)
    {
        if((v[i]>>k)&1) v1.push_back(v[i]);
        else v2.push_back(v[i]);
    }
    if(v1.empty()||v2.empty()) return dfs(v,k-1);//01Trie 只有一个分支 
    ll d1=dfs(v1,k-1),d2=dfs(v2,k-1);
    return min(max(d1,d2+(1<<k)),max(d1+(1<<k),d2));//有两个分支
}

int main()
{
    vector<ll> v; 
    scanf("%lld",&n);
    while(n--)
    {
        ll tmp;scanf("%lld",&tmp);
        v.push_back(tmp);
    }
    printf("%lld\n",dfs(v,30));
    return 0;
}

おすすめ

転載: www.cnblogs.com/oierwyh/p/12189209.html