zoukankan      html  css  js  c++  java
  • 2019牛客暑期多校训练营(第七场)- Governing sand

    线段树

    按照高度排序以后,对价格的值域建线段树,维护数量和总费用。

    每次枚举一个高度,假设该高度的树有m棵,比它的高的树显然要全部砍掉,直接用前缀和统计费用,又假设比他低的树有n棵,

    我们要砍的数量就是n - m + 1,在值域线段树里查询前n-m+1棵树的总费用即可。

    
    #include <bits/stdc++.h>
    #define INF 2333333333333333333
    #define full(a, b) memset(a, b, sizeof a)
    #define __fastIn ios::sync_with_stdio(false), cin.tie(0)
    #define range(x) (x).begin(), (x).end()
    #define pb push_back
    using namespace std;
    typedef long long LL;
    inline int lowbit(int x){ return x & (-x); }
    inline int read(){
        int ret = 0, w = 0; char ch = 0;
        while(!isdigit(ch)){
            w |= ch == '-', ch = getchar();
        }
        while(isdigit(ch)){
            ret = (ret << 3) + (ret << 1) + (ch ^ 48);
            ch = getchar();
        }
        return w ? -ret : ret;
    }
    template <typename A>
    inline A lcm(A a, A b){ return a / __gcd(a, b) * b; }
    template <typename A, typename B, typename C>
    inline A fpow(A x, B p, C lyd){
        A ans = 1;
        for(; p; p >>= 1, x = 1LL * x * x % lyd)if(p & 1)ans = 1LL * x * ans % lyd;
        return ans;
    }
    const int N = 200005;
    int n, cnt;
    LL sum[N<<2], pre[N], num[N], tree[N<<2], b[N];
    struct Tree{
        int h, c, p;
        Tree(){}
        Tree(int h, int c, int p): h(h), c(c), p(p){}
        bool operator < (const Tree &rhs) const {
            return h < rhs.h;
        }
    }t[N];
    
    void init(){
        cnt = 0;
        full(b, 0), full(pre, 0), full(num, 0);
        full(tree, 0), full(sum, 0);
    }
    
    void buildTree(int rt, int l, int r){
        if(l == r){
            tree[rt] = sum[rt] = 0;
            return;
        }
        int mid = (l + r) >> 1;
        buildTree(rt << 1, l, mid);
        buildTree(rt << 1 | 1, mid + 1, r);
    }
    
    void insert(int rt, int l, int r, int val, int k){
        tree[rt] += 1LL * k, sum[rt] += 1LL * val * k;
        if(l == r) return;
        int mid = (l + r) >> 1;
        if(val <= mid) insert(rt << 1, l, mid, val, k);
        else insert(rt << 1 | 1, mid + 1, r, val, k);
    }
    
    LL query(int rt, int l, int r, LL k){
        if(l == r) return l * k;
        int mid = (l + r) >> 1;
        if(k <= tree[rt << 1]) return query(rt << 1, l, mid, k);
        return sum[rt << 1] + query(rt << 1 | 1, mid + 1, r,  k - tree[rt << 1]);
    }
    
    int main(){
    
        while(~scanf("%d", &n)){
            init();
            for(int i = 1; i <= n; i ++){
                scanf("%d%d%d", &t[i].h, &t[i].c, &t[i].p);
            }
            sort(t + 1, t + n + 1);
            int j;
            for(int i = 1; i <= n; i = j){
                cnt ++, j = i;
                pre[cnt] += pre[cnt - 1], num[cnt] += num[cnt - 1];
                while(j <= n && t[j].h == t[i].h){
                    pre[cnt] += 1LL * t[j].c * t[j].p;
                    num[cnt] += t[j].p;
                    b[cnt] += t[j].p;
                    j ++;
                }
            }
            LL ans = INF;
            int tot = 0;
            for(int i = 1; i <= n; i = j){
                tot ++, j = i;
                LL cur = pre[cnt] - pre[tot];
                LL x = num[tot - 1];
                if(x - b[tot] + 1 > 0)
                    cur += query(1, 1, 200, x - b[tot] + 1);
                ans = min(ans, cur);
                while(j <= n && t[j].h == t[i].h) insert(1, 1, 200, t[j].c, t[j].p), j ++;
            }
            printf("%lld
    ", ans);
        }
        return 0;
    }
    
  • 相关阅读:
    12套有用的免费 PSD 格式 Android UI 素材
    使用 Canvas 和 JavaScript 创建逼真的下雨效果
    在网页设计中使用漂亮字体的16个优秀例子
    Koala – 开源的前端预处理器语言图形编译工具
    BackgroundCheck – 根据图片亮度智能切换元素样式
    经典网页设计:18个示例展示图片在网页中的使用
    TogetherJS – 酷!在网站中添加在线实时协作功能
    30个令人惊叹的灵感来自自然风光的网站设计《下篇》
    太有才了!创新的街头涂鸦手绘欣赏【中篇】
    15款美丽的设备模板,帮助展示你的 APP
  • 原文地址:https://www.cnblogs.com/onionQAQ/p/11322963.html
Copyright © 2011-2022 走看看