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);
    }
    
    
  • 相关阅读:
    [公告]博客园新服务器已下订单
    清除SearchNet.exe
    [新闻]微软将在2007年发布的Office产品阵容
    卸载Internet Explorer 7 Beta 2 Preview引起原来的IE无法正常使用
    博客园准备购买新服务器
    [微软活动公告]微软最有价值专家(MVP)四月份在线申请开始了
    [公告]今晚数据库迁移至新服务器
    请wz不要把别人的文章当作自己的文章发表
    SQL Server 2000 To SQL Server 2005
    [公告]博客园数据库已成功迁移至新服务器
  • 原文地址:https://www.cnblogs.com/Orz-IE/p/12039283.html
Copyright © 2011-2022 走看看