• BZOJ4198:[NOI2015]荷马史诗


    浅谈(Huffman)树:https://www.cnblogs.com/AKMer/p/10300870.html

    题目传送门:https://lydsy.com/JudgeOnline/problem.php?id=4198

    根据题意描述,这就是要你建一棵(k)(Huffman)树,并且还是棵(trie)树。

    然后记个深度,权值相同的时候选深度小的,就可以使得最长单词最短了,也就是这棵(trie)树会尽量扁。

    时间复杂度:(O(nlogn))

    空间复杂度:(O(nk))

    代码如下:

    #include <cstdio>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    
    const int maxn=2e5+5;
    
    ll sum_len;
    ll w[maxn];
    int n,tot,k,mx_dep;
    
    ll read() {
        ll x=0,f=1;char ch=getchar();
        for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
        for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
        return x*f;
    }
    
    struct node {
        ll cnt;
        int dep,id;
        
        node() {}
    
        node(ll _cnt,int _dep,int _id) {
            cnt=_cnt,dep=_dep,id=_id;
        }
    
        bool operator<(const node &a)const {
            if(cnt==a.cnt)return dep<a.dep;
            return cnt<a.cnt;
        }
    };
    
    struct Heap {
        int tot;
        node tree[maxn];
    
        void ins(node a) {
            tree[++tot]=a;
            int pos=tot;
            while(pos>1) {
                if(tree[pos]<tree[pos>>1])
                    swap(tree[pos],tree[pos>>1]),pos>>=1;
                else break;
            }
        }
    
        node pop() {
            node res=tree[1];
            tree[1]=tree[tot--];
            int pos=1,son=2;
            while(son<=tot) {
                if(son<tot&&tree[son|1]<tree[son])son|=1;
                if(tree[son]<tree[pos])
                    swap(tree[son],tree[pos]),pos=son,son=pos<<1;
                else break;
            }
            return res;
        }
    }T;
    
    struct trie {
        int son[maxn][10];
    
        void calc_ans(int u,int dep) {
            if(!son[u][0]) {
                mx_dep=max(mx_dep,dep);
                sum_len+=w[u]*dep;
                return;
            }
            for(int i=0;i<k;i++)
                calc_ans(son[u][i],dep+1);
        }
    }c;
    
    int main() {
        tot=n=read(),k=read();
        for(int i=1;i<=n;i++) {
            w[i]=read();
            T.ins(node(w[i],1,i));
        }
        while((n-1)%(k-1))
            tot++,n++,T.ins(node(0,1,tot));
        while(T.tot!=1) {
            ll tmp=0;int dep=0;++tot;
            for(int i=0;i<k;i++) {
                node word=T.pop();
                c.son[tot][i]=word.id;
                tmp+=word.cnt,dep=max(dep,word.dep);
            }
            T.ins(node(tmp,dep+1,tot));
        }
        c.calc_ans(T.tree[1].id,0);
        printf("%lld
    %d
    ",sum_len,mx_dep);
        return 0;
    }
    
  • 相关阅读:
    设置debian的静态IP
    《深入理解Java虚拟机》学习笔记之最后总结
    《深入理解Java虚拟机》学习笔记之字节码执行引擎
    《深入理解Java虚拟机》学习笔记之类加载
    《深入理解Java虚拟机》学习笔记之工具
    《深入理解Java虚拟机》学习笔记之内存回收
    Proxy源码解析
    Mysql索引
    搞定Hotspot-api
    JNI链接
  • 原文地址:https://www.cnblogs.com/AKMer/p/10311801.html
Copyright © 2020-2023  润新知