zoukankan      html  css  js  c++  java
  • BZOJ 5494: [2019省队联测]春节十二响 (左偏树 可并堆)

    题意

    分析

    稍微yy一下可以感觉就是一个不同子树合并堆,然后考场上写了一发左偏树,以为100分美滋滋.然而发现自己傻逼了,两个堆一一对应合并后剩下的一坨直接一次合并进去就行了.然鹅我这个sb把所有元素pop一次再merge进去…然后就O(n2)O(n^2) 60分滚粗了…

    啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊

    时间复杂度分析:

    • 每个点只会被pop出去一次,pop的时候伴随了一次pop一次merge.
    • 每一对父子关系merge了一次

    所以时间复杂度是O(nlogn)O(nlogn)的.

    CODE

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    char cb[1<<15],*cs=cb,*ct=cb;
    #define getc() (cs==ct&&(ct=(cs=cb)+fread(cb,1,1<<15,stdin),cs==ct)?0:*cs++)
    template<class T>inline void read(T &res) {
        char ch; while(!isdigit(ch=getchar()));
        for(res=ch-'0';isdigit(ch=getchar());res=res*10+ch-'0');
    }
    const int MAXN = 200005;
    int n, w[MAXN], fir[MAXN], to[MAXN], nxt[MAXN], cnt;
    inline void add(int u, int v) { to[++cnt] = v; nxt[cnt] = fir[u]; fir[u] = cnt; }
    struct LT {
        int ls, rs, dis;
    }t[MAXN];
    inline int merge(int x, int y) {
        if(!x || !y) return x + y;
        if(w[x] < w[y]) swap(x, y);
        t[x].rs = merge(t[x].rs, y);
        if(t[t[x].rs].dis > t[t[x].ls].dis)
            swap(t[x].ls, t[x].rs);
        t[x].dis = t[t[x].rs].dis + 1;
        return x;
    }
    inline int pop(int x) {
        int l = t[x].ls, r = t[x].rs;
        t[x].dis = t[x].ls = t[x].rs = 0;
        return merge(l, r);
    }
    inline int dfs(int x) {
        int u = 0, tmp;
        t[x].dis = t[x].ls = t[x].rs = 0;
        for(int i = fir[x], v; i; i = nxt[i]) {
            v = dfs(to[i]);
            tmp = 0;
            while(u && v) {
                int tmp1 = u; u = pop(u);
                int tmp2 = v; v = pop(v);
                tmp = merge(tmp, w[tmp1] > w[tmp2] ? tmp1 : tmp2);
            }
            if(u) tmp = merge(tmp, u);//就是这里我 sb地 pop出来又 push进去
            if(v) tmp = merge(tmp, v);
            u = tmp;
        }
        return merge(u, x);
    }
    int main () {
        read(n);
        for(int i = 1; i <= n; ++i) read(w[i]);
        for(int i = 2, x; i <= n; ++i) read(x), add(x, i);
        t[0].dis = -1;
        int rt = dfs(1);
        LL ans = 0;
        while(rt) ans += w[rt], rt = pop(rt);
        printf("%lld
    ", ans);
    }
    
    
  • 相关阅读:
    v-for给img的src动态赋值问题
    关于vue+axios上传文件的踩坑分析
    关于nth-of-type和nth-child的关系
    关于fetch
    关于移动端适配
    golang变量作用域问题-避免使用全局变量
    grpc-gateway:grpc转换为http协议对外提供服务
    google的grpc在golang中的使用
    golang中的rpc包用法
    homebrew常用命令
  • 原文地址:https://www.cnblogs.com/Orz-IE/p/12039283.html
Copyright © 2011-2022 走看看