Governing sand

链接:
https://ac.nowcoder.com/acm/contest/887/C
题意:
给n种树,其中每一种树都有高度h,每砍掉一棵树所需要的代价c,这种树的数量p。求花费最小的代价看砍树,使这群树中高度最大的树的数量大于树的总数量的一半。(砍树是需要直接把树砍完,不能砍一半~)
数据量:n<=1e5,h<=1e9,c<=200,p<=1e9
思路:
直接暴力的话,很明显是需要枚举每一种树为最高的树,然后去求需要砍的代价。直接暴力的话复杂度应该是(n* n)或者是 (n * c)。在这道题目中(n * c) 已经可以过了!不过太low,因为这道题c的数据量很明显可以出到1e9去的。我们就按照c的数据量是1e9来写(毕竟是训练)。
首先,依旧是需要枚举每一种树作为最高的树,然后需要判断代价,首先对树的高度从小到大排序,预处理后缀和,即s[i]表示到第i中树以及其之后的所有种类的树全部 砍掉之后需要的代价。还需要 建立权值线段树,维护权值为l~r这个区间的数的数量和代价和。然后从前向后进行枚举,到第i种树时,先把答案加上s[i+1]表示如果第i种树最高,那么它后面所有种类的树都要砍掉,然后去查询第i种树最高的情况下,前面最少需要砍掉树的代价是多少。需要注意的是多种树的高度相同的情况。
总的时间复杂度是O(n* log c)。
如果c到了1e9的时候 ,那么由于n最大是1e5,所以只需要离散化就能继续维护线段树了。(当然这道题目不需要)
比赛时队友做的这道题,当时在自闭另外一道题,这道题就只是大概读了一下题目,就没管了。比赛后敲了一下代码,感觉思路还挺简单,由于暴力都能过,所以成了一道签到题。但是后来比赛后我写线段树的时候wa了无数发,一是因为本来没有考虑 h相等的情况直接按照不相等处理是不对的,二是因为有一处int * int没有开 ll , 三是线段树中竟然有一个地方 = 写成了 == ,样例还莫名其妙的过了。。。
AC代码:

#include<bits/stdc++.h>
#include<algorithm>
#include<complex>
#include<iostream>
#include<iomanip>
#include<ostream>
#include<cstring>
#include<string.h>
#include<string>
#include<cstdio>
#include<cctype>
#include<vector>
#include<cmath>
#include<queue>
#include<set>
#include<stack>
#include<map>
#include<cstdlib>
#include<time.h>
#include<ctime>
#include<bitset>
// #include<ext/pb_ds/assoc_container.hpp>
// #include<ext/pb_ds/hash_policy.hpp>
#define pb push_back
#define _filein freopen("C:\\Users\\zsk18\\Desktop\\in.txt","r",stdin)
#define _fileout freopen("C:\\Users\\zsk18\\Desktop\\out.txt","w",stdout)
#define ok(i) printf("ok%d\n",i)
using namespace std;
// using namespace __gnu_pbds;
typedef double db;
typedef long long ll;
typedef pair<int,int>PII;
const double PI = acos(-1.0);
// const ll MOD=1e9+7;
const ll NEG=1e9+6;
const int MAXN=5e5+10;
const int INF=0x3f3f3f3f;
const ll ll_INF=9223372036854775807;
const double eps=1e-9;
struct trees
{ll h,c,p;bool operator <(const trees &a)const{return h<a.h;}
}tt[MAXN];
struct segment_tree
{ll l,r;ll num;ll w;
}t[MAXN];
int n;
ll s[MAXN];
void build(ll p,ll l,ll r)
{t[p].l=l,t[p].r=r;if(l==r){t[p].w=t[p].num=0;return;}ll mid=(l+r)>>1;build(p*2,l,mid);build(p*2+1,mid+1,r);t[p].num=t[p*2].num+t[p*2+1].num;t[p].w=t[p*2].w+t[p*2+1].w;return;
}
void change(ll p,ll tar,ll val)//p点的数量加上val个
{if(t[p].l==t[p].r){t[p].num+=val;t[p].w+=(val*tar);return;}ll mid=(t[p].l+t[p].r)>>1;if(tar<=mid)change(p*2,tar,val);else change(p*2+1,tar,val);t[p].num=t[p*2].num+t[p*2+1].num;t[p].w=t[p*2].w+t[p*2+1].w;return;
}
ll ask(ll p,ll val)
{if(val>=t[p].num)return t[p].w;if(t[p].l==t[p].r)return min(val*t[p].l,t[p].w);if(t[p*2].num>=val)return ask(p*2,val);else return t[p*2].w+ask(p*2+1,val-t[p*2].num);
}
int main()
{// _filein;while(~scanf("%d",&n)){memset(t,0,sizeof(t));memset(s,0,sizeof(s));ll l=200,r=0;for(int i=1;i<=n;i++){scanf("%lld%lld%lld",&tt[i].h,&tt[i].c,&tt[i].p);l=min((ll)l,tt[i].c);r=max((ll)r,tt[i].c);}sort(tt+1,tt+n+1);// ok(0);for(int i=n;i>=1;i--){s[i]=s[i+1]+(tt[i].c*tt[i].p);}build(1,l,r);ll ans=ll_INF;ll sum=0;// ok(1);for(int i=1;i<=n;i++){int k;ll now=0;for(k=0;i+k<=n;k++){if(tt[i].h!=tt[i+k].h)break;now+=tt[i+k].p; // printf("i=%d k=%d now=%I64d\n",i,k,now);}k--;ll mid=0;mid+=s[i+k+1];// ok(3);if(sum>=now)mid+=ask(1,sum-now+1);// printf("i=%d k=%d sum=%I64d now=%I64d mid=%I64d\n",i,k,sum,now,mid);ans=min(ans,mid);// ok(4);sum+=now;for(int j=i;j<=i+k;j++){change(1,tt[j].c,tt[j].p);}i+=k;}printf("%lld\n",ans);}return 0;
}

2019暑期训练——牛客第七场 C. Governing sand(权值线段树)相关推荐

  1. 【牛客 - 331E】炫酷划线(权值线段树,树状数组哈希,随机数)

    题干: 链接:https://ac.nowcoder.com/acm/contest/331/E 来源:牛客网 平面上有一个圆,圆环上按顺时针顺序分布着从1到n,一共n个点. 现在无聊的小希开始按某种 ...

  2. 【2019牛客暑期多校训练营(第二场)- E】MAZE(线段树优化dp,dp转矩阵乘法,线段树维护矩阵乘法)

    题干: 链接:https://ac.nowcoder.com/acm/contest/882/E?&headNav=acm 来源:牛客网 Given a maze with N rows an ...

  3. 2019牛客多校第七场 C Governing sand

    因为当时时间不怎么够就没写... 其实就是一个模拟题而已下面注释很清楚 链接:https://ac.nowcoder.com/acm/contest/887/C 来源:牛客网 时间限制:C/C++ 3 ...

  4. 牛客第七场 Sudoku Subrectangles

    链接:https://www.nowcoder.com/acm/contest/145/J 来源:牛客网 You have a n * m grid of characters, where each ...

  5. 【牛客 - 157C】PH试纸(前缀和,或权值线段树,主席树)

    题干: 链接:https://ac.nowcoder.com/acm/contest/157/C 来源:牛客网 题目描述 PH试纸,是一种检测酸碱度的试纸,试纸红色为酸性,蓝色为碱性. HtBest有 ...

  6. 牛客小白月赛28—E会当凌绝顶,一览众山小(线段树)

    链接:https://ac.nowcoder.com/acm/contest/7412/E 来源:牛客网 题目描述 牛牛最喜欢爬山了,他喜欢站在最高的山峰上展望. 牛牛来到山脚下,看到这里一共有 n ...

  7. 计蒜客 2020 蓝桥杯省赛 B 组模拟赛(五)E区间dp H 裴蜀 J dp A-J 权值线段树

    题目链接 因为要去笔试.所以只打了两个小时,有点求快,很多细节没写好就匆匆交,而且没有检查,打的有点菜 C-煎牛排 做法: 所有的面的个数sum=2*n   然后sum/(2*k)即可. ans=ma ...

  8. 2019牛客暑假多校训练赛第七场C Governing sand(暴力)

    题目链接:https://ac.nowcoder.com/acm/contest/887/C 题意:给出n种树和n个h[i],c[i],p[i]代表每种树的高度,砍掉一棵的花费,树的个数.现在要求砍掉 ...

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

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

最新文章

  1. 【python学习】模块random
  2. python 内置函数 sum()函数 求和函数
  3. 一个朋友的一天,太酸了!
  4. POJ 1061扩展欧几里得
  5. Zbrush风格化角色大神!带你感受别致性感美学!
  6. 2015春浙江省二级c语言,2015-2015年浙江省高校计算机等级考试二级C试题.doc
  7. mysql maximum idle_MySQL的MaxIdleConns不合理,会变成短连接的原因
  8. redhat multipath配置文件简要说明
  9. java滚动条调整数值_急..JAVA 在画布上画拖动滚动条可扩大缩小的长方形
  10. SqlZoo.net习题答案:Using the SELECT statement.【nobel】
  11. 时间+地区 选择器
  12. div在html中的好处,详解DIV+CSS布局的好处和意义
  13. C++对ascii文件按行和分隔符读取并显示
  14. STM32电机库(ST-MC-Workbench)学习记录——无感FOC代码生成
  15. 海信电视 LED55K370 升级固件总结【含固件下载地址】
  16. Flash 原版官网下载
  17. C#文件和文件文件夹排序
  18. 叶罗丽用计算机对话,叶罗丽小剧场:王默和水王子秀恩爱,俩人的对话也太搞笑了...
  19. 软件工程经济学期末复习
  20. STM32探索之路——使用JLink仿真器烧写固件的原理

热门文章

  1. 前端收集(前端学习资源)
  2. Android adb设备操作相关命令(断开连接、创建连接)
  3. 暴打JavaScript语法之getElementById()、getElementsByTagName()全能解释
  4. 2021下半年软考成绩什么时候出?
  5. 中国人工智能行业发展报告
  6. 京东api接口文档:获取京东APP端商品详情原数据 调用示例
  7. 7_6_Q题 Brackets 题解[POJ2955](区间DP)
  8. h5拼手气红包java_Java模拟微信发红包(普通红包、拼手气红包)
  9. 搜索+浏览合二为一的Slikk
  10. 计算机控制技术(第一章 绪论)