2019 cattle off more school seventh C-Governing sand (segment tree + enumeration)

Governing sand

Topic Portal

Problem-solving ideas

Each enumeration height as the maximum height, you need a minimum of money spent is: cut all altitudes higher than this tree of all spending + cut spending than the low height of the tree cheapest m tree, m height inside the lower number of cut required.

So, you can use weights tree line, in accordance with the height of the ascending order of the enumeration of the various species of trees placed to maintain the number of trees and tree for each node to spend, in order to obtain enumerated various height as the maximum height the minimum cost, the smallest is the answer. Need to take note of is that when you put a highly as the maximum height, you have to cut trees should not contain it, so seek first take, and then insert.

code show as below

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const int N = 100005;

struct T{
    int l, r;
    ll c;
    ll sum;
}tree[N<<2];

struct R{
    ll h, c, p;
    bool operator<(const R& a)const{
        return h < a.h;
    }
}a[N];

void build(int k, int l, int r)
{
    tree[k].l = l, tree[k].r = r;
    tree[k].c = tree[k].sum = 0;
    if(tree[k].l == tree[k].r)
        return;
    int mid = (tree[k].l + tree[k].r) / 2;
    build(2*k, l, mid);
    build(2*k+1, mid + 1, r);
}

void insert(int k, int x, ll c)
{
    if(tree[k].l == tree[k].r){
        tree[k].c += c;
        tree[k].sum += tree[k].l * c;
        return;
    }
    int mid = (tree[k].l + tree[k].r) / 2;
    if(x <= mid)
        insert(2*k, x, c);
    else
        insert(2*k+1, x, c);
    tree[k].c = tree[2*k].c + tree[2*k+1].c;
    tree[k].sum = tree[2*k].sum + tree[2*k+1].sum;
}

ll query(int k, ll x)
{
    if(tree[k].l == tree[k].r)
        return tree[k].l * x;
    if(tree[2*k].c >= x)
        return query(2*k, x);
    else {
        x -= tree[2*k].c;
        return query(2*k+1, x) + tree[2*k].sum;
    }
}

int main()
{
    int n;
    while(scanf("%d", &n) != EOF){
        ll sum = 0, num = 0;
        for(int i = 1; i <= n; i ++){
            scanf("%lld%lld%lld", &a[i].h, &a[i].c, &a[i].p);
            sum += a[i].c * a[i].p;
        }
        build(1, 1, 200);
        ll ans = 2000000000000000000LL;
        sort(a + 1, a + n + 1);
        for(int i = 1; i <= n; i ++){  
            sum -= a[i].p * a[i].c;
            num += a[i].p;
            ll ct = a[i].p;
            int j = i;
            while(j != n && a[j].h == a[j + 1].h){
                j ++;
                sum -= a[j].p * a[j].c;
                num += a[j].p;
                ct += a[j].p;
            }
            ll cut = num - 2 * ct + 1;
            ll cur = sum;
            if(cut > 0)
                cur += query(1, cut);
            ans = min(ans, cur);
            insert(1, a[i].c, a[i].p);
            while(i != n && a[i].h == a[i + 1].h){
                i ++;
                insert(1, a[i].c, a[i].p);
            }
        }
        printf("%lld\n", ans);
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/whisperlzw/p/11323466.html