Cattle off more school seventh C Governing sand tree line

Meaning of the questions:

There is a forest, woods different kinds of trees have a different number, height, cut down their prices. Now required to cut down some trees, so that more than half the height of the tallest trees in the total number of accounts for the rest of the tree, find the minimum cost.

answer:

Information maintenance of different types of trees with tree line, from left to right leaf node storage unit felled trees to spend a minimum of tree species from high to low height enumeration tree, this tree is the tallest trees left of each note every time this planting trees removed from the tree line, and then find the segment tree, shrub and tree height so that the ratio of the prefix required and the total cost even higher than the record of tree cut down to meet it.

Note that the same variety of tree height to special treatment.

#include<bits/stdc++.h>
#define MAXN 100005
#define LL long long
using namespace std;
struct Node{
    int l,r;
    int oneval;
    LL sumnum;
    LL sumval;
}node[MAXN<<2];
struct Tree{
    int oneval;
    int num;
    int height;
    int valrank;
}tree[MAXN];
inline bool cmp1(const Tree &a,const Tree &b){
    return a.oneval<b.oneval;
}
inline bool cmp2(const Tree &a,const Tree &b){
    return a.height>b.height;
}
void build(int l,int r,int x){
    node[x].l=l;
    node[x].r=r;
    if(l==r){
        node[x].sumnum=tree[l].num;
        node[x].oneval=tree[l].oneval;
        node[x].sumval=1LL*tree[l].num*tree[l].oneval;
        return ;
    }else{
        int mid=(l+r)/2;
        build(l,mid,x*2);
        build(mid+1,r,x*2+1);
    }
    node[x].sumnum=node[2*x].sumnum+node[2*x+1].sumnum;
    node[x].sumval=node[2*x].sumval+node[2*x+1].sumval;
    return ;
}
//LL query(int l,int r,int x){
//    if(l<=node[x].l && node[x].r<=r)return node[x].exis;
//    if(node[x].r<l || r<node[x].l)return 0;
//    LL ans=0;
//    if(l<=node[x*2].r)ans+=query(l,r,2*x);
//    if(node[x*2+1].l<=r)ans+=query(l,r,2*x+1);
//    return ans;
//}
void erase(int id,int x){
    if(node[x].l==node[x].r){
        node[x].sumnum=0;
        node[x].sumval=0;
        node[x].oneval=0;
        return ;
    }
    if(id<=node[x*2].r){
        erase(id,x*2);
    }else{
        erase(id,x*2+1);
    }
    node[x].sumval=node[x*2].sumval+node[x*2+1].sumval;
    node[x].sumnum=node[x*2].sumnum+node[x*2+1].sumnum;
    return ;
}
LL bsearch(LL last,int x){
    if(last<=0)return 0;
    if(node[x].l==node[x].r)return last*node[x].oneval;
    if(node[x].sumnum==last)return node[x].sumval;
    if(node[x].sumnum>last){
        if(last<=node[x*2].sumnum)return bsearch(last,x*2);
        else return node[x*2].sumval+bsearch(last-node[x*2].sumnum,x*2+1);
    }
}
int main(){
    int n;
    while(~scanf("%d",&n)){
        LL nowtrees=0;
        LL nowcost=0;
        LL minn=0x3f3f3f3f3f3f3f3f;
        for(int i=1;i<=n;i++){
            scanf("%d %d %d",&tree[i].height,&tree[i].oneval,&tree[i].num);
            nowtrees+=tree[i].num;
        }
        sort(tree+1,tree+1+n,cmp1);
        for(int i=1;i<=n;i++){
            tree[i].valrank=i;
        }
        build(1,n,1);
        sort(tree+1,tree+1+n,cmp2);
        for(int i=1;i<=n;i++){
            LL nextcost=0;
            LL talltrees=0;
            while(i<n && tree[i+1].height==tree[i].height){
                nowtrees-=tree[i].num;
                talltrees+=tree[i].num;
                erase(tree[i].valrank,1);
                nextcost+=1LL*tree[i].num*tree[i].oneval;
                ++i;
            }
            nowtrees-=tree[i].num;
            talltrees+=tree[i].num;
            erase(tree[i].valrank,1);
            nextcost+=1LL*tree[i].num*tree[i].oneval;
             
            minn=min(minn,nowcost+bsearch(nowtrees-talltrees+1,1));
//          printf("time%d:%lld\n",i,nowcost+bsearch(nowtrees-talltrees+1,1));
             
            nowcost+=nextcost;
        }
        printf("%lld\n",minn);
    }
}

 

Guess you like

Origin www.cnblogs.com/isakovsky/p/11329716.html