2019 가축 오프 더 학교 일곱 번째 C-경세 모래 (세그먼트 트리 + 열거)

경세 모래

주제 포털

문제 해결 아이디어

트리 저렴한 m 나무의 낮은 높이보다 모든 지출 + 컷 지출이 나무에 비해 모든 고도 높은 컷 : 각 열거 높이가 최대 높이로, 당신입니다 지출 돈의 최소 필요 필요한 컷의 하부 내측 번호 m 높이.

그래서, 당신은 최대 높이로 열거 된 다양한 높이를 얻기 위해 지출하는 각 노드에 나무와 나무의 수를 유지하기 위해 배치 나무의 다양한 종의 열거의 오름차순의 높이에 따라, 무게 트리 라인을 사용할 수 있습니다 최소 비용, 최소의 대답이다. 당신이 최대 높이로 매우 둘 때, 당신은 그것을 포함 할 수 없습니다 나무를 절단해야한다는 것입니다 주목 걸릴 수 있으므로 추구 첫째로 포획 한 다음 삽입해야합니다.

다음 코드는

#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;
}

추천

출처www.cnblogs.com/whisperlzw/p/11323466.html