区间前k小的和(权值线段树+离散化)--2019牛客多校第7场C--砍树
题目链接: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--砍树的更多相关文章
- 2019牛客多校第七场E Find the median 权值线段树+离散化
Find the median 题目链接: https://ac.nowcoder.com/acm/contest/887/E 题目描述 Let median of some array be the ...
- 2019牛客多校第七场E Find the median 离散化+线段树维护区间段
Find the median 题意 刚开始集合为空,有n次操作,每次操作往集合里面插入[L[i],R[i]]的值,问每次操作后中位数是多少 分析 由于n比较大,并且数可以达到1e9,我们无法通过权值 ...
- 2019牛客多校第四场K number dp or 思维
number 题意 给一个数字串,问有几个子串是300的倍数 分析 dp写法:这题一看就很dp,直接一个状态dp[i][j]在第i位的时候膜300的余数是j左过去即可.这题比赛的时候样例老是少1,后面 ...
- 线段树维护区间前k小
线段树维护区间前k小 $ solution: $ 觉得超级钢琴太麻烦?在这里线段树提供一条龙服务 . 咳咳,开始讲正题!这道题我们有一个和超级钢琴复杂度一样 $ ~O(~\sum x\times lo ...
- 2020牛客多校第八场K题
__int128(例题:2020牛客多校第八场K题) 题意: 有n道菜,第i道菜的利润为\(a_i\),且有\(b_i\)盘.你要按照下列要求给顾客上菜. 1.每位顾客至少有一道菜 2.给顾客上菜时, ...
- 【XSY2720】区间第k小 整体二分 可持久化线段树
题目描述 给你你个序列,每次求区间第\(k\)小的数. 本题中,如果一个数在询问区间中出现了超过\(w\)次,那么就把这个数视为\(n\). 强制在线. \(n\leq 100000,a_i<n ...
- 2019牛客训练赛第七场 C Governing sand 权值线段树+贪心
Governing sand 题意 森林里有m种树木,每种树木有一定高度,并且砍掉他要消耗一定的代价,问消耗最少多少代价可以使得森林中最高的树木大于所有树的一半 分析 复杂度分析:n 1e5种树木,并 ...
- 左闭右开线段树 2019牛客多校(第七场)E_Find the median(点代表区间
目录 题意 一种解析 AC_Code @(2019第七场牛客 E_Find the median 左闭右开线段树) 题意 链接:here 我理解的题意就是:初始序列为空,有\(n(400000)\)次 ...
- 【BZOJ3110】K大数查询(权值线段树套线段树+标记永久化,整体二分)
题意:有N个位置,M个操作.操作有两种,每次操作 如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c 如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数是 ...
随机推荐
- MySQL_(Java)提取工具类JDBCUtils
MySQL_(Java)使用JDBC向数据库发起查询请求 传送门 MySQL_(Java)使用JDBC创建用户名和密码校验查询方法 传送门 MySQL_(Java)使用preparestatement ...
- Redis 4.x 5.x 未授权访问
环境搭建 5.0版本下载 wget http://download.redis.io/releases/redis-5.0.5.tar.gz tar xzf redis-5.0.0.tar.gz cd ...
- [CSP-S模拟测试]:数学课(找规律+数学)
题目传送门(内部题145) 输入格式 从$math.in$读入数据. 第一行两个数,为$n,q$.接下来$q$行每行一个数$m$,询问大小为$m$的$A$一共有多少个. 输出格式 输出答案到$math ...
- webservice代码编写主要包括服务器端发布和客户端调用。
一.java工程发布,java工程调用 (一).服务器端的编写 1.在eclipse里新建java project工程,创建功能类,通过关键字@webservice(name="newI ...
- Python中的OS对路径的操作以及应用
目录处理 OS目录处理目录-->路径,文件夹 文件:html 1. 新建和删除一个目录import os #引入os目录from xx import xxos.mkdir("D:\\P ...
- python:BeautifulSoup学习
上一篇说到用BeautifulSoup解析源代码,下面我们就来实战一下: from bs4 import BeautifulSoup html = urllib.request.urlopen('ht ...
- koa 基础(四)get 传值 以及获取 get 传值
1.get 传值 以及获取 get 传值 app.js /** * get 传值 以及获取 get 传值 */ // 引入模块 const Koa = require('koa'); const ro ...
- 让SpringBoot工程支持热部署
下载地址:https://files.cnblogs.com/files/xiandedanteng/SpringBootWeb-1_20190928.rar 修改Java文件后,每次要重启才好用,修 ...
- ambari部署Hadoop集群(1)
本例使用hortonworks 提供了 ambari 的安装方法,而且还很详细.以下是在 centos7 上的安装步骤. 基础配置: 1. 修改电脑的主机名 hostnamectl set-hostn ...
- linux 基础 文件操作
cat -A /etc/passwdnl -ba passwd cat -A man_db.conf more man_db.conf less man_db.conf head -n 5 /var/ ...