题目链接: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. npm+cnpm+vuecli3打包相关

    1,npm install和cnpm install时的不同 https://blog.csdn.net/csm0912/article/details/90264026 2,npm设置和查看仓库源 ...

  2. 如何使用python将指定文件里的数据读取到字典里

    list_dict_all = [] #创建一个空列表,全局变量,用来存放字典def AddtoDict(str_1): # 定义一个函数,功能:把文件里面的内容添加到字典中 list_str1 = ...

  3. 转贴 使用正则表达式解析一般sql语句(C++)

    https://blog.csdn.net/dreamgchuan/article/details/47715743 --END--2019年9月5日11点58分

  4. Bootstrap-CSS:目录

    ylbtech-Bootstrap-CSS:目录 1.返回顶部 1.   2. 2.返回顶部   3.返回顶部   4.返回顶部   5.返回顶部 1.   2.   6.返回顶部   7.返回顶部 ...

  5. Collapse 折叠面板

    通过折叠面板收纳内容区域 基础用法 可同时展开多个面板,面板之间不影响 <el-collapse v-model="activeNames" @change="ha ...

  6. 通过ssh管道连接内网数据库(mysql)

    公网连接内网数据库(如云数据库)时,通常需要白名单:如果不是白名单IP,通常需要一个跳板机(类似代理)来连接内网数据库, 下方以mysql为例(其他数据库基本一致): import pymysql a ...

  7. asp.net core mvc View Component 应用

    ViewComponent 1.View 组件介绍 在ASP.NET CORE MVC中,View组件有点类似于partial views,但是他们更强大,View组件不能使用model bindin ...

  8. MySQL数据表列转行

    简单例子 数据结构如下 use dataTest create table t_score ( name ) , subject ), grade ,) ) INSERT INTO `t_score` ...

  9. 基于axis的WebService的案例

    1.axis axis是Apache旗下产品,它是一个webservice容器,可被用于创建.部署和运行webservice.网址http://axis.apache.org/,网址上的部分截图如下. ...

  10. Django>ORM字段和参数

    Django之ORM字段和参数   字段 常用字段 AutoField 自增int自增列,必须填入参数 primary_key=True. 当model中如果没有自增列,则自动会创建一个列名为id的列 ...