2019牛客训练赛第七场 C Governing sand 权值线段树+贪心
Governing sand
题意
森林里有m种树木,每种树木有一定高度,并且砍掉他要消耗一定的代价,问消耗最少多少代价可以使得森林中最高的树木大于所有树的一半
分析
复杂度分析:n 1e5种树木,并且砍树肯定是从便宜的砍,有区间性,可以考虑线段树,每次枚举一种高度,先把高于其高度的全部砍掉,再砍低于他的使得满足大于一半的条件,砍低于他的肯定是从花费低的开始砍,所以就是一个选前k小的问题,这样就是一颗权值线段树的事情了
坑点:不同种的树木可能高度相同
#include<bits/stdc++.h>
#define pb push_back
#define F first
#define S second
#define pii pair<int,int>
#define mkp make_pair
typedef long long ll;
#define int long long
using namespace std;
const int maxn =1e5+5;
ll tr[maxn<<2];
int sz,n;
int c[maxn],id[maxn];
ll sum[maxn];
struct Node{
int h,p,c;
}a[maxn];
void build(int o,int l,int r){
sum[o]=tr[o]=0;
if(l==r)return ;
int mid=l+r>>1;
build(o<<1,l,mid);
build(o<<1|1,mid+1,r);
}
void update(int o,int l,int r,int p,int v){
if(l==r){
tr[o]+=v;
sum[o]+=v*c[p];
}
else {
int mid=l+r>>1;
if(p<=mid)update(o<<1,l,mid,p,v);
else update(o<<1|1,mid+1,r,p,v);
tr[o]=tr[o<<1|1]+tr[o<<1];
sum[o]=sum[o<<1]+sum[o<<1|1];
}
}
ll query(int o,int l,int r,int num){
if(l==r){
return min(1ll*num,tr[o])*1ll*c[l];
}
int mid=l+r>>1;
if(tr[o<<1]>=num)return query(o<<1,l,mid,num);
else return sum[o<<1]+query(o<<1|1,mid+1,r,num-tr[o<<1]);
}
int32_t main(){
while(scanf("%lld",&n)!=EOF){
long long sumcost=0;
for(int i=1;i<=n;i++){
scanf("%lld%lld%lld",&a[i].h,&a[i].c,&a[i].p);
sumcost+=a[i].p*a[i].c;
c[i]=a[i].c;
}
sort(c+1,c+1+n);
sz=unique(c+1,c+1+n)-(c+1);
build(1,1,sz);
sort(a+1,a+1+n,[](Node a,Node b){
return a.h<b.h;});
long long qnum=0;
long long ans=1e18;
for(int i=1;i<=n;i++){
id[i]=lower_bound(c+1,c+1+sz,a[i].c)-c;
}
for(int i=1;i<=n;){
int p=i+1;
ll nowhnum=a[i].p;
int cnt=0;
while(p<=n&&a[p].h==a[i].h){
nowhnum+=a[p].p;
cnt++;
p++;
}
for(int j=i;j<=cnt+i;j++){
sumcost-=a[j].p*a[j].c;
}
if(nowhnum>qnum){
ans=min(sumcost,ans);
}
else {
ans=min(ans,sumcost+query(1,1,sz,qnum-nowhnum+1));
}
for(int j=i;j<=cnt+i;j++){
qnum+=a[j].p;
update(1,1,sz,id[j],a[j].p);
}
i=p;
}
printf("%lld\n",ans);
}
return 0;
}
2019牛客训练赛第七场 C Governing sand 权值线段树+贪心的更多相关文章
- 2019牛客多校第七场E Find the median 离散化+线段树维护区间段
Find the median 题意 刚开始集合为空,有n次操作,每次操作往集合里面插入[L[i],R[i]]的值,问每次操作后中位数是多少 分析 由于n比较大,并且数可以达到1e9,我们无法通过权值 ...
- 牛客多校第七场 C Governing sand 线段树
题意: 有一个树林,树林中不同种类的树有不同的数量,高度,砍伐它们的价格.现在要求砍掉一些树,使得高度最高的树占剩下的树的总数的一半以上,求最小花费. 题解: 用线段树维护不同种类树的信息,叶子节点从 ...
- 牛客多校第三场 G Removing Stones(分治+线段树)
牛客多校第三场 G Removing Stones(分治+线段树) 题意: 给你n个数,问你有多少个长度不小于2的连续子序列,使得其中最大元素不大于所有元素和的一半 题解: 分治+线段树 线段树维护最 ...
- Find the median(2019年牛客多校第七场E题+左闭右开线段树)
题目链接 传送门 题意 每次往集合里面添加一段连续区间的数,然后询问当前集合内的中位数. 思路 思路很好想,但是卡内存. 当时写的动态开点线段树没卡过去,赛后机房大佬用动态开点过了,\(tql\). ...
- 2019牛客多校第七场E Find the median 权值线段树+离散化
Find the median 题目链接: https://ac.nowcoder.com/acm/contest/887/E 题目描述 Let median of some array be the ...
- 2019牛客多校第七场H Pair 数位DP
题意:给你一个3个数A, B, C问有多少对pair(i, j),1 <= i <= A, 1 <= j <= B, i AND j > C或 i XOR j < ...
- 2019牛客多校第七场C-Governing sand(线段树+枚举)
Governing sand 题目传送门 解题思路 枚举每一种高度作为最大高度,则需要的最小花费的钱是:砍掉所有比这个高度高的树的所有花费+砍掉比这个高度低的树里最便宜的m棵树的花费,m为高度低的里面 ...
- 2019牛客多校第七场 F Energy stones 树状数组+算贡献转化模拟
Energy stones 题意 有n块石头,每块有初始能量E[i],每秒石头会增长能量L[i],石头的能量上限是C[i],现有m次时刻,每次会把[s[i],t[i]]的石头的能量吸干,问最后得到了多 ...
- 2019牛客多校第八场 F题 Flowers 计算几何+线段树
2019牛客多校第八场 F题 Flowers 先枚举出三角形内部的点D. 下面所说的旋转没有指明逆时针还是顺时针则是指逆时针旋转. 固定内部点的答案的获取 anti(A)anti(A)anti(A)或 ...
随机推荐
- react引入ggEditor流程图
遇到的问题 1.propsAPI获取不到内容:withPropsAPI包裹的组件必须是GGEditor的子组件. 2.自定义组件如何使用:正确的办法是通过config配置,参照上面的代码(之前我在在内 ...
- PP: Extracting statisticla graph features for accurate and efficient time series classification
Problem: TSC, time series classification; Traditional TSC: find global similarities or local pattern ...
- bootstrap 兼容 IE8
在 html 中引用 <!-- bootstrap 兼容 IE8 --> <script src="../../jsapi/js/html5shiv.min.js" ...
- Vue图片验证码-自定义组件高级版
最近项目中要用到图片验证码,网上一查有很多,基本都是千篇一律的4位纯数字验证码.首先得感谢那位一代目兄台提供的模板,由于不能满足需求,所以对其进行了改造升级. 经改造的图片验证码能满足一下情形使用:① ...
- 小白的java学习之路 “ 变量、数据类型和运算符”
一.变量: 1.什么是变量? 变量是一个数据存储空间的表示 变量由:变量名 变量类型 变量的值 2.创造变量的两种方法: 1.声明-->赋值-->取值 //声明变量 int money ...
- Spark性能优化指南——初级篇
原文来我的公众号:Spark性能优化指南——初级篇 一. Spark作业原理 我们使用spark-submit提交一个Spark作业之后,这个作业就会启动一个对应的Driver进程.该进程是向集群管理 ...
- 剑指offer-面试题23-链表中环的入口节点-双指针
/* 题目: 如果链表中包含环,如何找出环的入口? */ /* 思路: 双指针: 1.判断是否有环. fast指针一次2步,slow指针一次1步,当fast与slow相遇时,说明有环. 2.判断环路中 ...
- openlayers显示区域
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...
- PAT (Advanced Level) Practice 1120 Friend Numbers (20 分) (set)
Two integers are called "friend numbers" if they share the same sum of their digits, and t ...
- Cloudera Manager和CDH版本的对应关系
来源:https://www.cloudera.com/documentation/enterprise/release-notes/topics/rn_consolidated_pcm.html#c ...