zoukankan      html  css  js  c++  java
  • 01字典树逆应用+树上dp——cf1285D

    不知道为啥只开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(); 
    } 
  • 相关阅读:
    【小工具】根据定义的白名单字段进行Bean的拷贝
    【Java】Java8的Lambda入门记录
    【Java】浅谈Java IO
    【工具】我的Git学习日志
    【Java】浅谈HashMap
    【Java】Java Queue的简介
    【ZooKeeper】ZooKeeper入门流水记
    【MQTT】Mosquitto的安装与使用流水记
    【数据结构】简单的数据结构图解
    【Java多线程】JDK1.5并发包API杂谈
  • 原文地址:https://www.cnblogs.com/zsben991126/p/12274664.html
Copyright © 2011-2022 走看看