题意:

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

题解:

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

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

#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. 发光LED压降与工作电流总结

    一.常用的普通贴片0603LED 红色的压降为1.82-1.88V,电流5-8mA 绿色的压降为1.75-1.82V,电流3-5mA 橙色的压降为1.7-1.8V,电流3-5mA 兰色的压降为3.1- ...

  2. ecshop前台英文后台中文的设置方法

    ecshop前台英文后台中文的设置方法 这里有两种方法: 第一种方法: 打开 admin/includes/init.php 文件 找到$_CFG = load_config(); 在它下面增加一行代 ...

  3. HTML标签分类总结

    块级元素和行内元素块级元素address - 地址blockquote - 块引用center - 举中对齐块dir - 目录列表div - 常用块级容易,也是css layout的主要标签dl - ...

  4. 使用Vue和djangoframwork完成登录页面构建 001

    使用Vue和djangoframwork完成登录页面构建 001 环境的搭建 首先,我在我的电脑的F盘创建了一个文件夹 forNote,进入到这个文件夹中 F:\forNote> vue环境的搭 ...

  5. linux IPC 消息队列

    消息队列函数原型 在建立IPC通讯时(如消息队列,共享内存)必须建立一个ID值.通常情况下,这个ID值由ftok函数得到 #inlcude <sys/types.h> #include & ...

  6. 【Codeforces Round #429 (Div. 2) C】Leha and Function

    [Link]:http://codeforces.com/contest/841/problem/C [Description] [Solution] 看到最大的和最小的对应,第二大的和第二小的对应. ...

  7. ES6 教程

    上次分享了es6开发环境的搭建,本次接着分享es6常用的特性. es6常用的语法参考   :    https://blog.csdn.net/itzhongzi/article/details/73 ...

  8. [Go语言]cgo用法演示

        经历了数十年发展的C语言,各种各样的现成的库已经非常丰富.通过cgo,可以在Go语言中使用C语言代码,充分利用好现有的“轮子”. 本文所有代码,在下述环境中调试通过: Windows 8.1 ...

  9. makefile.new(7117) : error U1087: cannot have : and :: dependents for same target

    makefile.new(7117) : fatal error U1087: cannot have : and :: dependents for same target(2012-05-21 2 ...

  10. (动态改变数据源遇到的问题)ORACLE11g:No Dialect mapping for JDBC type: -9解决方案

    在动态改变数据源时 hibernate配置不能使用Oracle官方的方言(org.hibernate.dialect.Oracle10gDialect) 做法写一个方言扩展类,缺什么类型,添加什么类型 ...