zoukankan      html  css  js  c++  java
  • 【APIO 2012】dispatching

    Solution

    想存一下左偏树的模板。

    我们发现容量上限是不变的,那么就可以贪心地依次选取每个点子树中的最大值删去。

    就可以啦。

    Code

    #include <cstdio>
    #include <iostream>
    using namespace std;
    typedef long long ll;
    
    const int N = 1e5 + 5;
    
    int head[N], dot[N << 1], nxt[N << 1], cnt, m;
    ll ans;
    
    struct LT {
        int f[N], son[N][2], val[N], dis[N], siz[N];
        ll s[N], l[N];
    
        void init(const int n) {
            for(int i = 1; i <= n; ++ i) {
                son[i][0] = son[i][1] = dis[i] = s[i] = 0;
                f[i] = i; siz[i] = 1;
            }
        }
    
        int Find(const int x) {return x == f[x] ? x : f[x] = Find(f[x]);}
    
        bool cmp(const int x, const int y) {return Find(x) == Find(y);}
    
        int unite(int x, int y) {
            if(! x || ! y) return x + y;
            if(val[x] < val[y]) swap(x, y);
            son[x][1] = unite(son[x][1], y); f[son[x][1]] = x;
            if(dis[son[x][0]] < dis[son[x][1]]) swap(son[x][0], son[x][1]);
            dis[x] = dis[son[x][1]] + 1;
            return x;
        }
    
        int del(const int x) {
            int l = son[x][0], r = son[x][1];
            son[x][0] = son[x][1] = dis[x] = 0;
            f[l] = l; f[r] = r;
            return unite(l, r);
        }
    
        void solve(const int x, const int fa) {
            for(int i = head[x]; i; i = nxt[i]) {
                int v = dot[i];
                if(v == fa) continue;
                solve(v, x);
                siz[x] += siz[v]; s[x] += s[v];
                f[x] = unite(f[x], f[v]);
            }
            while(s[x] > m) {
                s[x] -= val[f[x]]; -- siz[x];
                f[x] = unite(son[f[x]][0], son[f[x]][1]);
            }
            ans = max(ans, l[x] * siz[x]);
        }
    }T;
    
    void addEdge(const int u, const int v) {
        dot[++ cnt] = v; nxt[cnt] = head[u]; head[u] = cnt;
    }
    
    int read() {
        int x = 0, f = 1; char s;
        while((s = getchar()) < '0' || s > '9') if(s == '-') f = -1;
        while(s >= '0' && s <= '9') {x = (x << 1) + (x << 3) + (s ^ 48); s = getchar();}
        return x * f;
    }
    
    int main() {
        int x, n, root;
        n = read(), m = read();
        T.init(n);
        for(int i = 1; i <= n; ++ i) {
            x = read(), T.s[i] = T.val[i] = read(), T.l[i] = read();
            if(x) addEdge(x, i);
            else root = i;
        }
        T.solve(root, 0);
        printf("%lld
    ", ans);
        return 0;
    }
    

    (mathtt{upt})Running Away From the Barn 与此题方法相同,将 val 改为 dep 即可过。

  • 相关阅读:
    上传高德地图-express框架
    express不是内部命令
    elasticSearch 安装
    elasticSearch 分布式安装
    mongoDB基本操作
    [是题解哦] 洛谷 P1865 A % B Problem
    [是题解哦] 洛谷 P1531 I Hate It
    [是题解哦] 洛谷 P1195 口袋的天空
    [是题解哦] 洛谷 P1536 村村通
    [是模板哦] 快速读入
  • 原文地址:https://www.cnblogs.com/AWhiteWall/p/12611718.html
Copyright © 2011-2022 走看看