【CF799E】Aquarium decoration 线段树
【CF799E】Aquarium decoration
题意:有n个物品,小A和小B各自喜欢其中的某些物品,一件物品可能既被小A喜欢又被小B喜欢,也可能既不被小A喜欢又不被小B喜欢。每个物品都有一个价格$c_i$,让你选出其中的m件物品,满足小A和小B都至少喜欢其中的k件,且总价格最小。
$n\le 2\times 10^5,c_i\le 10^9$
题解:我们把物品分成四部分:0,A,B,AB,并分别排序,然后我们枚举AB中选了i个。接着我们可以二分:在A,B,0中选择的价格最大的物品的价格mid,假设A中有a个数小于等于mid,则我们要从中选max(a,k)个,同理B中选max(b,k)个,C中选m-i-max(a,k)-max(b,k)个。发现这个显然是可以二分的。如果把二分放到线段树上的话,则时间复杂度是$O(n\log n)$。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define lson x<<1
#define rson x<<1|1
using namespace std;
typedef long long ll;
const int maxn=200010;
ll ans;
int n,m,k,na,nb,nc,nd,N;
int A[maxn],B[maxn],C[maxn],D[maxn],v[maxn],tag[maxn],p[maxn];
int ca[maxn<<2],cb[maxn<<2],cd[maxn<<2],ta[maxn],tb[maxn],td[maxn];
ll sa[maxn],sb[maxn],sd[maxn],ref[maxn]; bool cmp(const int &a,const int &b)
{
return v[a]<v[b];
}
void insert(int l,int r,int x,int a,int b,int c)
{
if(c==0) ca[x]=b;
if(c==1) cb[x]=b;
if(c==2) cd[x]=b;
if(l==r) return ;
int mid=(l+r)>>1;
if(a<=mid) insert(l,mid,lson,a,b,c);
else insert(mid+1,r,rson,a,b,c);
}
ll query(int l,int r,int x,int a)
{
if(l==r)
return sa[max(ca[x],a)]+sb[max(cb[x],a)]+sd[cd[x]]-ref[l]*(max(ca[x],a)+max(cb[x],a)+cd[x]+k-a-m);
int mid=(l+r)>>1,t=max(ca[lson],a)+max(cb[lson],a)+cd[lson]+k-a;
if(t>=m) return query(l,mid,lson,a);
return query(mid+1,r,rson,a);
}
void build(int l,int r,int x)
{
if(l==r)
{
ca[x]=ta[l],cb[x]=tb[l],cd[x]=td[l];
return ;
}
int mid=(l+r)>>1;
build(l,mid,lson),build(mid+1,r,rson);
ca[x]=ca[rson],cb[x]=cb[rson],cd[x]=cd[rson];
}
inline int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-') f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+(gc^'0'),gc=getchar();
return ret*f;
}
int main()
{
n=rd(),m=rd(),k=rd();
int i,a,b;
for(i=1;i<=n;i++) v[i]=rd(),p[i]=i;
sort(p+1,p+n+1,cmp);
for(i=1;i<=n;i++)
{
if(i==1||v[p[i]]>ref[N]) ref[++N]=v[p[i]];
v[p[i]]=N;
}
a=rd();
for(i=1;i<=a;i++) b=rd(),tag[b]|=1;
a=rd();
for(i=1;i<=a;i++) b=rd(),tag[b]|=2;
for(i=1;i<=n;i++)
{
if(tag[i]==0) D[++nd]=ref[v[i]],td[v[i]]++;
if(tag[i]==1) A[++na]=ref[v[i]],ta[v[i]]++;
if(tag[i]==2) B[++nb]=ref[v[i]],tb[v[i]]++;
if(tag[i]==3) C[++nc]=ref[v[i]];
}
sort(A+1,A+na+1),sort(B+1,B+nb+1),sort(C+1,C+nc+1),sort(D+1,D+nd+1);
for(i=1;i<=N;i++) ta[i]+=ta[i-1],tb[i]+=tb[i-1],td[i]+=td[i-1];
for(i=1;i<=na;i++) sa[i]=sa[i-1]+A[i];
for(i=1;i<=nb;i++) sb[i]=sb[i-1]+B[i];
for(i=1;i<=nd;i++) sd[i]=sd[i-1]+D[i];
ll sum=0; ans=1ll<<60;
build(0,N,1);
for(i=0;i<=min(nc,m);i++)
{
sum+=C[i];
if(min(na,nb)>=k-i&&2*k-i<=m&&i+na+nb+nd>=m)
ans=min(ans,sum+query(0,N,1,k-i));
}
if(ans==1ll<<60) puts("-1");
else printf("%lld",ans);
return 0;
}
【CF799E】Aquarium decoration 线段树的更多相关文章
- bzoj3932--可持久化线段树
题目大意: 最近实验室正在为其管理的超级计算机编制一套任务管理系统,而你被安排完成其中的查询部分.超级计算机中的 任务用三元组(Si,Ei,Pi)描述,(Si,Ei,Pi)表示任务从第Si秒开始,在第 ...
- codevs 1082 线段树练习 3(区间维护)
codevs 1082 线段树练习 3 时间限制: 3 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 给你N个数,有两种操作: 1:给区 ...
- codevs 1576 最长上升子序列的线段树优化
题目:codevs 1576 最长严格上升子序列 链接:http://codevs.cn/problem/1576/ 优化的地方是 1到i-1 中最大的 f[j]值,并且A[j]<A[i] .根 ...
- codevs 1080 线段树点修改
先来介绍一下线段树. 线段树是一个把线段,或者说一个区间储存在二叉树中.如图所示的就是一棵线段树,它维护一个区间的和. 蓝色数字的是线段树的节点在数组中的位置,它表示的区间已经在图上标出,它的值就是这 ...
- codevs 1082 线段树区间求和
codevs 1082 线段树练习3 链接:http://codevs.cn/problem/1082/ sumv是维护求和的线段树,addv是标记这歌节点所在区间还需要加上的值. 我的线段树写法在运 ...
- PYOJ 44. 【HNSDFZ2016 #6】可持久化线段树
#44. [HNSDFZ2016 #6]可持久化线段树 统计 描述 提交 自定义测试 题目描述 现有一序列 AA.您需要写一棵可持久化线段树,以实现如下操作: A v p x:对于版本v的序列,给 A ...
- CF719E(线段树+矩阵快速幂)
题意:给你一个数列a,a[i]表示斐波那契数列的下标为a[i],求区间对应斐波那契数列数字的和,还要求能够维护对区间内所有下标加d的操作 分析:线段树 线段树的每个节点表示(f[i],f[i-1])这 ...
- 【BZOJ-3779】重组病毒 LinkCutTree + 线段树 + DFS序
3779: 重组病毒 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 224 Solved: 95[Submit][Status][Discuss] ...
- 【BZOJ-3673&3674】可持久化并查集 可持久化线段树 + 并查集
3673: 可持久化并查集 by zky Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 1878 Solved: 846[Submit][Status ...
随机推荐
- GridView动态添加列并判断绑定数据DataTable的列类型控制展示内容
此篇随笔是2013年根据项目需求开发记录的,不一定符合大众口味,只需了解开发思路,毕竟解决方案多种多样. 下面简单说说需求点吧: (1)通过下拉列表可以选择一个DataSet(数据集),一个DataS ...
- 小波变换——哈尔小波,Haar
哈尔小波转换是于1909年由Alfréd Haar所提出,是小波变换(Wavelet transform)中最简单的一种变换,也是最早提出的小波变换. Alfréd Haar,1885~1933,匈牙 ...
- IT运维队伍的管理
如何建设一支能够解决问题.创造价值.有活力的.不断进取的IT运维团队,并带领这支团队,充分发挥这个团队的优势力量,是运维业务有效开展的关键.运维 策略是直接体现运维业务的经济价值所在.好的运维措施.方 ...
- 阿里云提出的漏洞(Phpcms V9某处逻辑问题导致getshell漏洞解决方法)的问题
最近从阿里云云盾检测流出来的,相比使用阿里云服务器的朋友已经收到漏洞提醒:Phpcms V9某处逻辑问题导致getshell漏洞解决方法,这个漏洞怎么办呢?CMSYOU在这里找到针对性解决办法分享给大 ...
- 【12-06】A股主要指数的市盈率(PE)估值高度
全指材料(SH000987) - 2018-12-06日,当前值:12.043,平均值:30.37,中位数:26.0097,当前 接近历史新低.全指材料(SH000987)的历史市盈率PE详情 中证煤 ...
- EXCEPTION:FATAL: UNABLE TO CREATE ‘…GIT/INDEX.LOCK’ FILE EXISTS
FATAL: UNABLE TO CREATE ‘…GIT/INDEX.LOCK’ FILE EXISTS Hi, Today I will share you my other experience ...
- mongodb 初学 目录
mongodb 初学 索引 啦啦啦 MongoDB 教程 NoSQL 简介 MongoDB 简介 Windows 平台安装 MongoDB Linux平台安装MongoDB mongodb 在 Ubu ...
- linux 停止对某个端口的监听
1.通过"netstat -anp" 来查看哪些端口被打开. 2.关掉对应的应用程序,则端口就自然关闭了,如:"kill -9 PID" (PID:进程号)
- Nginx(十二)-- Nginx+keepalived实现高可用
1.前提 两台Linux服务器,IP分别为192.168.80.128 和 192.168.80.129,都安装Nginx和keepalived,并启动. 2.配置双机热备 1.将192.168.80 ...
- JavaWeb学习总结(十五)Jsp中提交的表单的get和post的两种方式
两者的比较: Get方式: 将请求的参数名和值转换成字符串,并附加在原来的URL之后,不安全 传输的数据量较小,一般不能大于2KB: post方式: 数量较大: 请求的参数和值放在HTML的请求头中, ...