题意:

有一个树林,树林中不同种类的树有不同的数量,高度,砍伐它们的价格。现在要求砍掉一些树,使得高度最高的树占剩下的树的总数的一半以上,求最小花费。

题解:

用线段树维护不同种类树的信息,叶子节点从左到右存储单棵砍伐花费最小的树,从高度由高到低枚举树的种类,每次记这种树为留下的最高的树,每次将此种树从线段树上删除,然后求线段树上,使得矮树与高树比例满足要求的前缀和,还要记录比它高的树砍掉的总花费。

注意多种树同一高度要特殊处理。

#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<<];
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)/;
build(l,mid,x*);
build(mid+,r,x*+);
}
node[x].sumnum=node[*x].sumnum+node[*x+].sumnum;
node[x].sumval=node[*x].sumval+node[*x+].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=;
node[x].sumval=;
node[x].oneval=;
return ;
}
if(id<=node[x*].r){
erase(id,x*);
}else{
erase(id,x*+);
}
node[x].sumval=node[x*].sumval+node[x*+].sumval;
node[x].sumnum=node[x*].sumnum+node[x*+].sumnum;
return ;
}
LL bsearch(LL last,int x){
if(last<=)return ;
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*].sumnum)return bsearch(last,x*);
else return node[x*].sumval+bsearch(last-node[x*].sumnum,x*+);
}
}
int main(){
int n;
while(~scanf("%d",&n)){
LL nowtrees=;
LL nowcost=;
LL minn=0x3f3f3f3f3f3f3f3f;
for(int i=;i<=n;i++){
scanf("%d %d %d",&tree[i].height,&tree[i].oneval,&tree[i].num);
nowtrees+=tree[i].num;
}
sort(tree+,tree++n,cmp1);
for(int i=;i<=n;i++){
tree[i].valrank=i;
}
build(,n,);
sort(tree+,tree++n,cmp2);
for(int i=;i<=n;i++){
LL nextcost=;
LL talltrees=;
while(i<n && tree[i+].height==tree[i].height){
nowtrees-=tree[i].num;
talltrees+=tree[i].num;
erase(tree[i].valrank,);
nextcost+=1LL*tree[i].num*tree[i].oneval;
++i;
}
nowtrees-=tree[i].num;
talltrees+=tree[i].num;
erase(tree[i].valrank,);
nextcost+=1LL*tree[i].num*tree[i].oneval; minn=min(minn,nowcost+bsearch(nowtrees-talltrees+,));
// printf("time%d:%lld\n",i,nowcost+bsearch(nowtrees-talltrees+1,1)); nowcost+=nextcost;
}
printf("%lld\n",minn);
}
}

牛客多校第七场 C Governing sand 线段树的更多相关文章

  1. 牛客多校第四场sequence C (线段树+单调栈)

    牛客多校第四场sequence C (线段树+单调栈) 传送门:https://ac.nowcoder.com/acm/contest/884/C 题意: 求一个$\max {1 \leq l \le ...

  2. 2019年牛客多校第四场 B题xor(线段树+线性基交)

    题目链接 传送门 题意 给你\(n\)个基底,求\([l,r]\)内的每个基底是否都能异或出\(x\). 思路 线性基交板子题,但是一直没看懂咋求,先偷一份咖啡鸡板子写篇博客吧~ 线性基交学习博客:传 ...

  3. 2019牛客多校第四场C-sequence(单调栈+线段树)

    sequence 题目传送门 解题思路 用单调栈求出每个a[i]作为最小值的最大范围.对于每个a[i],我们都要乘以一个以a[i]为区间内最小值的对应的b的区间和s,如果a[i] > 0,则s要 ...

  4. 牛客多校第十场 F Popping Balloons 线段树维护稀疏矩阵

    题意: 给定一个稀疏矩阵,里面有若干个气球,让你横着开三枪,竖着开三枪,问最多能打爆多少气球,要求相同方向,相邻两枪必须间隔r. 题解: 横向记录每列有多少个气球,分别在哪行上. 然后把这个数据改造成 ...

  5. 2019牛客训练赛第七场 C Governing sand 权值线段树+贪心

    Governing sand 题意 森林里有m种树木,每种树木有一定高度,并且砍掉他要消耗一定的代价,问消耗最少多少代价可以使得森林中最高的树木大于所有树的一半 分析 复杂度分析:n 1e5种树木,并 ...

  6. 牛客多校第七场 C Bit Compression 思维

    链接:https://www.nowcoder.com/acm/contest/145/C来源:牛客网 A binary string s of length N = 2n is given. You ...

  7. Find the median(2019年牛客多校第七场E题+左闭右开线段树)

    题目链接 传送门 题意 每次往集合里面添加一段连续区间的数,然后询问当前集合内的中位数. 思路 思路很好想,但是卡内存. 当时写的动态开点线段树没卡过去,赛后机房大佬用动态开点过了,\(tql\). ...

  8. 2019牛客多校第七场E Find the median 权值线段树+离散化

    Find the median 题目链接: https://ac.nowcoder.com/acm/contest/887/E 题目描述 Let median of some array be the ...

  9. 两两内积为0(牛客多校第七场)-- CDMA

    题意: 构造一个n*n的矩阵,元素只能是-1或1,任意两行内积为0(两两相乘加起来和为0). 思路: #define IOS ios_base::sync_with_stdio(0); cin.tie ...

随机推荐

  1. 创建一个wx.App的子类

    #_author:来童星#date:2019/12/20#创建一个wx.App的子类import wxclass App(wx.App): #初始化方法 def OnInit(self): frame ...

  2. springMVC配置文件 的约束

    <?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.spr ...

  3. Dart编程实例 - 相等和关系操作符

    Dart编程实例 - 相等和关系操作符 void main() { var num1 = 5; var num2 = 9; var res = num1>num2; print('num1 gr ...

  4. ajax 实战使用

    注意ajax 必须放在script脚本中使用 ajax用于前端朝后端提交数据,并且后端函数处理好结果返回给success函数作为回调函数给前端,前端拿到后端传来的值,比如code==0 来做相应的前端 ...

  5. Python 爬取各大代理IP网站(元类封装)

    import requests from pyquery import PyQuery as pq base_headers = { 'User-Agent': 'Mozilla/5.0 (Windo ...

  6. NX二次开发-基于NX开发向导模板的NX对Excel读写操作(OLE方式(COM组件))

    在看这个博客前,请读者先去完整看完:NX二次开发-基于MFC界面的NX对Excel读写操作(OLE方式(COM组件))https://ufun-nxopen.blog.csdn.net/article ...

  7. [bzoj3073] Journeys 题解(线段树优化建图)

    Description Seter建造了一个很大的星球,他准备建造N个国家和无数双向道路.N个国家很快建造好了,用1..N编号,但是他发现道路实在太多了,他要一条条建简直是不可能的!于是他以如下方式建 ...

  8. (转)oracle group by 和order by的关系(在一起使用注意事项)

    转:http://lzfhope.blog.163.com/blog/static/636399220092554045196/ 环境:oracle 10g单单group by 或者order by本 ...

  9. VMProtect使用小计【二】 – 加壳查看

    Release 我这里使用的是Release的版本,Debug的版本分析没有多少的必要,因为程序发布过之后就是Release的,我们先看一下这个文件 原程序分析 使用OD打开VMProtectDemo ...

  10. (转载)前端构建工具gulpjs的使用介绍及技巧

    本文转载自:https://www.cnblogs.com/2050/p/4198792.html gulpjs是一个前端构建工具,与gruntjs相比,gulpjs无需写一大堆繁杂的配置参数,API ...