• bzoj2809 [Apio2012]dispatching


    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2809

    【题解】

    枚举选定的领导者,从领导者下属选择一坨他们的薪水<=m,那么肯定贪心选。

    下面一坨选可以用主席树,为了使他们连起来,用DFS序。。

    我真是傻逼dfs序都会写错。。

    # include <stdio.h>
    # include <string.h>
    # include <algorithm>
    // # include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    const int M = 2e5 + 10;
    const int mod = 1e9+7;
    
    # define RG register
    # define ST static
    
    int n, C, cap;
    int c[M], L[M];
    
    int head[M], nxt[M], to[M], tot=0;
    inline void add(int u, int v) {
        ++tot; nxt[tot] = head[u]; head[u] = tot; to[tot] = v;
    }
    inline void adde(int u, int v) {
        add(u, v); add(v, u);
    }
    
    int in[M], out[M], DFN=0, dfn[M];
    inline void dfs(int x, int fa) {
        in[x] = ++DFN; dfn[DFN] = x;
        for (int i=head[x]; i; i=nxt[i]) {
            if(to[i] == fa) continue;
            dfs(to[i], x);
        }
        out[x] = DFN;
    }
    
    int rt[M];
    namespace CMT {
        const int M = 5e6 + 10;
        ll s[M];
        int ch[M][2], siz, sz[M];
        inline void edt(int &x, int y, int l, int r, int pos) {
            x = ++siz; ch[x][0] = ch[y][0], ch[x][1] = ch[y][1];
            s[x] = s[y] + pos; sz[x] = sz[y] + 1;
            if(l == r) return;
            int mid = l+r>>1;
            if(pos <= mid) edt(ch[x][0], ch[y][0], l, mid, pos);
            else edt(ch[x][1], ch[y][1], mid+1, r, pos);
        }
        inline ll query(int x, int y, int l, int r, ll res) {
            if(res<l) return 0;
            if(l == r) return min(res/l, (ll)sz[y]-sz[x]);
            ll le = s[ch[y][0]] - s[ch[x][0]];
            int mid = l+r>>1;
            if(le <= res) return (ll)sz[ch[y][0]] - sz[ch[x][0]] + query(ch[x][1], ch[y][1], mid+1, r, res-le);
            else return query(ch[x][0], ch[y][0], l, mid, res);
        }
    }
    
    int main() {
        scanf("%d%d", &n, &C);
        for (int i=1, u; i<=n; ++i) {
            scanf("%d%d%d", &u, c+i, L+i);
            if(u) adde(u, i);
            else cap = i;
        }
        dfs(cap, 0);
        for (int i=1; i<=n; ++i) 
            CMT::edt(rt[i], rt[i-1], 1, 1e9, c[dfn[i]]);
        ll ans = 0;
        int ps;
        for (int i=1; i<=n; ++i) {
            ll t = L[i];
            t = t * CMT::query(rt[in[i]-1], rt[out[i]], 1, 1e9, C);
            if(t > ans) {
                ans = t;
                ps = i;
            }
        }
        printf("%lld
    ", ans);
        return 0;
    }
    View Code
  • 相关阅读:
    SQLite常用SQL语句
    delphi设计浮动窗口
    在Delphi中使用键盘勾子获取键盘输入(译--5月7日)
    Delphi制作软键盘
    Delphi格式化输出函数(1): Format
    《你不知道的 CSS》之等比例缩放的盒子
    请用心练完这16个webpack小例子
    JavaScript高级内容笔记:原型链、继承、执行上下文、作用域链、闭包
    表格组件神器:bootstrap table详细使用指南
    玩转JavaScript正则表达式
  • 原文地址:https://www.cnblogs.com/galaxies/p/bzoj2809.html
Copyright © 2020-2023  润新知