题目链接:https://ac.nowcoder.com/acm/contest/887/C?&headNav=acm

题意:

给你 n 种树,有 高度,花费和数量 ,现在问你最少需要花多少钱使得最高的树的数量占总数的一半以上。

思路:

其实就是先把高度离散化一下(不离散化也没事),再按树的高度从低到高排一下序,枚举最高的树。

比如当前枚举的是 H,那花费就是(>H)的树的所有花费+(<H)的最多剩下num-1棵树,用权值线段树记录花费和花费的个数,每次查询前k小个就可以了。

 #define IOS ios_base::sync_with_stdio(0); cin.tie(0);
#include <cstdio>//sprintf islower isupper
#include <cstdlib>//malloc exit strcat itoa system("cls")
#include <iostream>//pair
#include <fstream>
#include <bitset>
//#include <map>
//#include<unordered_map> https://ac.nowcoder.com/acm/contest/887/C?&headNav=acm
#include <vector>
#include <stack>
#include <set>
#include <string.h>//strstr substr
#include <string>
#include <time.h>//srand(((unsigned)time(NULL))); Seed n=rand()%10 - 0~9;
#include <cmath>
#include <deque>
#include <queue>//priority_queue<int, vector<int>, greater<int> > q;//less
#include <vector>//emplace_back
//#include <math.h>
//#include <windows.h>//reverse(a,a+len);// ~ ! ~ ! floor
#include <algorithm>//sort + unique : sz=unique(b+1,b+n+1)-(b+1);+nth_element(first, nth, last, compare)
using namespace std;//next_permutation(a+1,a+1+n);//prev_permutation
#define fo(a,b,c) for(register int a=b;a<=c;++a)
#define fr(a,b,c) for(register int a=b;a>=c;--a)
#define mem(a,b) memset(a,b,sizeof(a))
#define pr printf
#define sc scanf
#define ls rt<<1
#define rs rt<<1|1
void swapp(int &a,int &b);
double fabss(double a);
int maxx(int a,int b);
int minn(int a,int b);
int Del_bit_1(int n);
int lowbit(int n);
int abss(int a);
const long long INF=(1LL<<);
const double E=2.718281828;
const double PI=acos(-1.0);
const int inf=(<<);
const double ESP=1e-;
const int mod=(int)1e9+;
const int N=(int)1e5+; int n;
struct node_
{
int h,num,cost;
friend bool operator<(node_ a,node_ b)
{
return a.h>b.h;
}
}arr[N];
int b[N];
int LS(int n)
{
int m=;
for(int i=; i<=n; ++i)
b[++m]=arr[i].h;
sort(b+,b++m);
m=unique(b+,b++m)-b-;
for(int i=; i<=n; ++i)
arr[i].h=lower_bound(b+,b++m,arr[i].h)-b;
return m;
}
//================================================离散化;
struct node
{
long long cnt;
long long sum;
}tr[N<<];
void Build(int l,int r,int rt)
{
tr[rt].sum=tr[rt].cnt=;
if(l==r)return;
int mid=(l+r)>>;
Build(l,mid,rt<<);
Build(mid+,r,rt<<|);
}
void update_dot(int cost,int cnt,int l,int r,int rt)
{
tr[rt].sum+=cost*cnt;
tr[rt].cnt+=cnt;
if(l==r)return; int mid=(l+r)>>;
if(cost<=mid)
update_dot(cost,cnt,l,mid,rt<<);
else
update_dot(cost,cnt,mid+,r,rt<<|);
}
long long Query(long long sum,int l,int r,int rt)
{
if(sum==)return ;
if(l==r)
{
return sum*l;
}
int mid=(l+r)>>;
long long ans=; if(sum<=tr[ls].cnt)
ans+=Query(sum,l,mid,ls);
else
ans+=Query(sum-tr[ls].cnt,mid+,r,rs)+tr[ls].sum;
return ans;
}
void check(int pos,int l,int r,int rt)
{
if(l==r)
{
pr("%lld %lld\n",tr[rt].cnt,tr[rt].sum);
return ;
}
int mid=(l+r)>>; if(pos<=mid)
check(pos,l,mid,rt<<);
else
check(pos,mid+,r,rt<<|);
}
void C(int tot)
{
fo(i,,n)
check(i,,tot,);
pr("----------------------------------\n");
}
long long dp[N];
vector<vector<int> >v(N); int main()
{
while(~sc("%d",&n))
{
fo(i,,n)sc("%d%d%d",&arr[i].h,&arr[i].cost,&arr[i].num);
arr[n+].num=arr[n+].cost=arr[n+].h=;
LS(n);
sort(arr+,arr++n);
fo(i,,n)
dp[i]=dp[i-]+arr[i].cost*arr[i].num,v[i].clear();
long long ans=INF;
int vcnt=;
long long cnt=;
long long CNT=;
int ncnt=;
for(int i=n;i>=;--i)
{
if(arr[i].h!=arr[i+].h)
v[++vcnt].push_back(i);
else
v[vcnt].push_back(i);
}
Build(,,);
int sz=v[].size();//vector用来存相同高度的树团体
fo(i,,sz-)
update_dot(arr[v[][i]].cost,arr[v[][i]].num,,,),CNT+=arr[v[][i]].num;
ans=min(ans,dp[n-sz]);
ncnt=sz;
fo(i,,vcnt)
{
int sz_=v[i].size();
fo(j,,sz_-)
cnt+=arr[v[i][j]].num;
ncnt+=sz_;
long long k=max(0LL,CNT-(cnt-));
ans=min(ans,Query(k,,,)+dp[n-ncnt]);
fo(j,,sz_-)
update_dot(arr[v[i][j]].cost,arr[v[i][j]].num,,,);
CNT+=cnt;
cnt=;
}
pr("%lld\n",ans);
}
return ;
} /**************************************************************************************/ int maxx(int a,int b)
{
return a>b?a:b;
} void swapp(int &a,int &b)
{
a^=b^=a^=b;
} int lowbit(int n)
{
return n&(-n);
} int Del_bit_1(int n)
{
return n&(n-);
} int abss(int a)
{
return a>?a:-a;
} double fabss(double a)
{
return a>?a:-a;
} int minn(int a,int b)
{
return a<b?a:b;
}

区间前k小的和(权值线段树+离散化)--2019牛客多校第7场C--砍树的更多相关文章

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

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

  2. 2019牛客多校第七场E Find the median 离散化+线段树维护区间段

    Find the median 题意 刚开始集合为空,有n次操作,每次操作往集合里面插入[L[i],R[i]]的值,问每次操作后中位数是多少 分析 由于n比较大,并且数可以达到1e9,我们无法通过权值 ...

  3. 2019牛客多校第四场K number dp or 思维

    number 题意 给一个数字串,问有几个子串是300的倍数 分析 dp写法:这题一看就很dp,直接一个状态dp[i][j]在第i位的时候膜300的余数是j左过去即可.这题比赛的时候样例老是少1,后面 ...

  4. 线段树维护区间前k小

    线段树维护区间前k小 $ solution: $ 觉得超级钢琴太麻烦?在这里线段树提供一条龙服务 . 咳咳,开始讲正题!这道题我们有一个和超级钢琴复杂度一样 $ ~O(~\sum x\times lo ...

  5. 2020牛客多校第八场K题

    __int128(例题:2020牛客多校第八场K题) 题意: 有n道菜,第i道菜的利润为\(a_i\),且有\(b_i\)盘.你要按照下列要求给顾客上菜. 1.每位顾客至少有一道菜 2.给顾客上菜时, ...

  6. 【XSY2720】区间第k小 整体二分 可持久化线段树

    题目描述 给你你个序列,每次求区间第\(k\)小的数. 本题中,如果一个数在询问区间中出现了超过\(w\)次,那么就把这个数视为\(n\). 强制在线. \(n\leq 100000,a_i<n ...

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

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

  8. 左闭右开线段树 2019牛客多校(第七场)E_Find the median(点代表区间

    目录 题意 一种解析 AC_Code @(2019第七场牛客 E_Find the median 左闭右开线段树) 题意 链接:here 我理解的题意就是:初始序列为空,有\(n(400000)\)次 ...

  9. 【BZOJ3110】K大数查询(权值线段树套线段树+标记永久化,整体二分)

    题意:有N个位置,M个操作.操作有两种,每次操作 如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c 如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数是 ...

随机推荐

  1. 用Python操作excel文档

    使用Python第三方库 这一节我们学习如何使用Python去操作Excel文档.如果大家有人不知道Excel的话,那么建议先学一学office办公基础.这里想要操作Excel,必须安装一个Pytho ...

  2. Centos安装成功后配置网络

    一.设置IP地址.网关DNS 说明:CentOS 7.0默认安装好之后是没有自动开启网络连接的! cd /etc/sysconfig/network-scripts/ #进入网络配置文件目录 vi i ...

  3. LeetCode 42. 接雨水(Trapping Rain Water)

    题目描述 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水. 上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况 ...

  4. vue 按需加载,缓存,导航守卫

    开发中的注意事项:代码性能的优化 1. 减少对第三方的依赖,降低耦合度 2. 加强组件的重复利用率 3. 按需加载 4. 缓存 (尽量发送请求后保存数据) 5. 开发过程中,尽量有着面向对象的思想,这 ...

  5. itertools模块中的product方法

    itertools模块中的product方法 itertools.product(*iterables[, repeat]) 笛卡尔积 创建一个迭代器,生成表示item1,item2等中的项目的笛卡尔 ...

  6. silverlight开发实例(Prism+MVVM+RIA)(二)--创建shell及用户登录

    在上篇基本说清了本项目的基本框架,下面开始说下项目的加载和shell.开始之前在建立EF时出现了一个问题,我在数据库中建立了视图,而在EF导入视图时出现因无法匹配主键导致无法导入视图的问题,检查发现是 ...

  7. 如何优雅的给TDatetimePicker控件赋值(Delphi)

    给DatetimePicker赋值时,可以通过界面设置赋值,也可以通过代码赋值. 通常,我们会给表示起始时间的dtp赋值为 00:00:00,给表示结束时间的dtp赋值为23:59:59. 代码如下: ...

  8. 【URL 的编码、解码】

    工具类 /** * URLEncodeTest.java * weixinTest * * Function: TODO * * ver date author * ───────────────── ...

  9. Beego开启热升级

    1.打开配置 beego.BConfig.Listen.Graceful = true 2.写入pid 程序入口main()函数里写入pid func writePid() { fileName := ...

  10. 怎样将DataGrip连接到MS SQL Server?

    DataGrip支持几乎所有主流的关系数据库产品,如DB2.Derby.H2.MySQL.Oracle.PostgreSQL.SQL Server.Sqllite及Sybase等,并且提供了简单易用的 ...