区间前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大的数是 ...
随机推荐
- 基于node、webpack、搭建一个koa服务器
1.首先需要node(去官网下载) 2.见一个文件夹 比如koa cmd——r cd koa文件 3.npm init 4.安装webpack (本地安装 ...
- 2、dubbo基础知识
1.简介 2.dubbo架构 3.dubbo环境搭建 注意:cmd命令都是在bin目录的地址栏直接输入 xxx.cmd 4.配置dubbo-admin 步骤一: 步骤二: 步骤三: 步骤四: 步骤五: ...
- cin.clear()与cin.sync()的使用
cin.clear()与cin.sync()使用是有先后顺序的. 他们的作用: cin.clear(); //将流中的所有状态都重设为有效值 cin.sync();//清空流 在输入错误的情况下,如果 ...
- websphere gc策略调整
根据应用服务器处理的特性,适配不同的gc策略,验证程序最适合程序的gc策略: server.xml路径: xmlcells/PBOCCell/nodes/PBOCNode01/servers/PBOC ...
- Response.AddHeader("Content-Disposition", "attachment; filename=" + file.Name) 中文显示乱码
如果file.Name为中文则乱码.解决办法是方法1:response.setHeader("Content-Disposition", "attachment; fil ...
- 取得远端相应Json并转化为Java对象(嵌套对象)二
工程下载链接:https://files.cnblogs.com/files/xiandedanteng/JsonParse20190929.rar 客户端: 如果从Restful Service取得 ...
- [Java]用于将链表变成字符串并在元素之间插入分隔符的有用函数“String.join”
将链表变成字符串并在元素之间插入分隔符,这种动作最常见于组合sql文“select a,b,c from tb”这种场景scenario,其中a,b,c你是存贮在链表中的, 如果要加逗号要么在循环中识 ...
- java 包引入时*会全部加载吗
有一个虚拟机参数: -XX:+TraceClassLoading 这两种写法,最终加载的类是一样的. 对比了一下输出的都是618行
- 七十八:flask.Restful之flask-Restful标准化返回参数以及准备数据
对于一个视图函数,可以指定好数据结构和字段用于返回,以后使用ORM模型或者自定义的模型的时候,它会自动获取模型中相应的字段,生成json数据,然后再返回给前端,这需要导入flask_restful.m ...
- Ubunut16.04 安装 Theano+GPU
1. 更新NVIDIA显卡驱动 安装好系统之后首先在系统更新管理器中更新显卡驱动,如下图 点击Apply Changes 2. 安装numpy,scipy,theano pip安装即可 sudo ...