Governing sand
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;
}