题解

将所有物品分成四类,分别为两人共同喜欢的,只有一人喜欢的,没人喜欢的。

首先,先从两人共同喜欢的物品里找出 \(k\) 个,这时,就要从剩余的找出 \(\rm m-k\) 个,而且是最小的。

用一棵权值线段树维护,因为值域太大,所以离散化或动态开点。

之后,指向共同喜欢的物品数量的指针递减,直至 \(0\) 同时增加选取其它物品的量,删除选了的,加上没选的。

因为指针单调递减,所以复杂度为 \(\mathcal O\rm (nlogn)\)

Code
#include<bits/stdc++.h>
#define ri register signed
#define p(i) ++i
using namespace std;
namespace IO{
char buf[1<<21],*p1=buf,*p2=buf;
#define gc() p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++
template<typename T>inline void read(T &x) {
ri f=1;x=0;register char ch=gc();
while(ch<'0'||ch>'9') {if (ch=='-') f=0;ch=gc();}
while(ch>='0'&&ch<='9') {x=(x<<1)+(x<<3)+(ch^48);ch=gc();}
x=f?x:-x;
}
}
using IO::read;
namespace nanfeng{
#define pb(x) push_back(x)
#define FI FILE *IN
#define FO FILE *OUT
template<typename T>inline T cmax(T x,T y) {return x>y?x:y;}
template<typename T>inline T cmin(T x,T y) {return x>y?y:x;}
typedef long long ll;
static const int N=2e5+7,INF=1e9;
int v[N],vis1[N],vis2[N],a,b,n,m,k,nm;
ll sum,ans=1e18;
vector<int> lv[3];
inline int cmp(int x,int y) {return v[x]<v[y];}
struct Seg{
#define ls(x) T[x].l
#define rs(x) T[x].r
struct segmenttree{int nm,l,r;ll sum;}T[N<<6];
int st[N<<6],cnt,tot,rt;
inline void up(int x) {
T[x].nm=T[ls(x)].nm+T[rs(x)].nm;
T[x].sum=T[ls(x)].sum+T[rs(x)].sum;
}
inline int New() {return cnt?st[cnt--]:p(tot);}
inline void Del(int &x) {st[p(cnt)]=x;x=0;}
void update(int &x,int p,int l,int r) {
if (!x) x=New();
if (l==r) return (void)(T[x].sum+=p,p(T[x].nm));
int mid(l+r>>1);
if (p<=mid) update(ls(x),p,l,mid);
else update(rs(x),p,mid+1,r);
up(x);
}
void del(int &x,int p,int l,int r) {
if (l==r) {
--T[x].nm,T[x].sum-=p;
if (!T[x].nm) Del(x);
return;
}
int mid(l+r>>1);
if (p<=mid) del(ls(x),p,l,mid);
else del(rs(x),p,mid+1,r);
up(x);
}
ll query(int x,int siz,int l,int r) {
if (!x) return 0;
if (l==r) return (ll)l*(ll)siz;
int mid(l+r>>1);
ll res(0);
if (T[ls(x)].nm>=siz) res+=query(ls(x),siz,l,mid);
else res+=T[ls(x)].sum+query(rs(x),siz-T[ls(x)].nm,mid+1,r);
return res;
}
}T;
inline int main() {
// FI=freopen("nanfeng.in","r",stdin);
// FO=freopen("nanfeng.out","w",stdout);
read(n),read(m),read(k);
if (m<k) {puts("-1");return 0;}
for (ri i(1);i<=n;p(i)) read(v[i]);
read(a);
for (ri i(1),id;i<=a;p(i)) read(id),vis1[id]=1;
read(b);
for (ri i(1),id;i<=b;p(i)) read(id),vis2[id]=1;
for (ri i(1);i<=n;p(i)) {
if (vis1[i]&&vis2[i]) lv[0].pb(i);
else if (vis1[i]) lv[1].pb(i);
else if (vis2[i]) lv[2].pb(i);
else T.update(T.rt,v[i],1,INF);
}
sort(lv[0].begin(),lv[0].end(),cmp);
sort(lv[1].begin(),lv[1].end(),cmp);
sort(lv[2].begin(),lv[2].end(),cmp);
ri bc=cmin((int)lv[0].size(),k),fr=1;
ri siz1=lv[1].size(),siz2=lv[2].size();
if (bc+siz1<k) {puts("-1");return 0;}
if (bc+siz2<k) {puts("-1");return 0;}
for (ri i(0);i<bc;p(i)) sum+=v[lv[0][i]],p(nm);
while(fr+bc<=k) sum+=v[lv[1][fr-1]],sum+=v[lv[2][fr-1]],nm+=2,p(fr);
for (ri i(fr);i<=siz1;p(i)) T.update(T.rt,v[lv[1][i-1]],1,INF);
for (ri i(fr);i<=siz2;p(i)) T.update(T.rt,v[lv[2][i-1]],1,INF);
if (nm>m) {puts("-1");return 0;}
ans=cmin(ans,sum+T.query(T.rt,m-nm,1,INF));
bc-=1,nm-=1;
if (bc>=0) T.update(T.rt,v[lv[0][bc]],1,INF),sum-=v[lv[0][bc]];
while(bc>=0&&bc+siz1>=k&&bc+siz2>=k) {
while(fr+bc<=k) {
sum+=(ll)v[lv[1][fr-1]]+(ll)v[lv[2][fr-1]];
T.del(T.rt,v[lv[1][fr-1]],1,INF);
T.del(T.rt,v[lv[2][fr-1]],1,INF);
nm+=2;
p(fr);
}
if (nm>m) break;
ans=cmin(ans,sum+T.query(T.rt,m-nm,1,INF));
--bc,--nm;
if (bc>=0) T.update(T.rt,v[lv[0][bc]],1,INF),sum-=v[lv[0][bc]];
}
printf("%lld\n",ans);
return 0;
}
}
int main() {return nanfeng::main();}

NOIP 模拟 $23\; \rm 赛$的更多相关文章

  1. NOIP 模拟 $23\; \rm 题$

    题解 \(by\;zj\varphi\) 考虑 \(\rm DP\) 设 \(dp_{k}(S)\) 表示前 \(k\) 个人来后 \(S\) 集合中的苹果都存在的概率是否大于 \(0\) 考虑倒着转 ...

  2. NOIP 模拟 $23\; \rm 联$

    题解 \(by\;zj\varphi\) 区间上的问题,一般都用线段树来解决(但是这题也可以用 \(\rm ODT\)) 对于每段段区间设置三个参数,分别表示这个区间是否只有 \(1\) 或 \(0\ ...

  3. noip模拟23[联·赛·题]

    \(noip模拟23\;solutions\) 怎么说呢??这个考试考得是非常的惨烈,一共拿了70分,为啥呢 因为我第一题和第三题爆零了,然后第二题拿到了70分,还是贪心的分数 第一题和第二题我调了好 ...

  4. [考试总结]noip模拟23

    因为考试过多,所以学校的博客就暂时咕掉了,放到家里来写 不过话说,vscode的markdown编辑器还是真的很好用 先把 \(noip\) 模拟 \(23\) 的总结写了吧.. 俗话说:" ...

  5. 5.23考试总结(NOIP模拟2)

    5.23考试总结(NOIP模拟2) 洛谷题单 看第一题第一眼,不好打呀;看第一题样例又一眼,诶,我直接一手小阶乘走人 然后就急忙去干T2T3了 后来考完一看,只有\(T1\)骗到了\(15pts\)[ ...

  6. [SinGuLaRiTy] NOIP互测模拟赛

    [SinGuLaRiTy-1045] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. 源文件名 输入输出文件 时间限制 内存限制 淘气的cch ...

  7. NOIP模拟 1

    NOIP模拟1,到现在时间已经比较长了.. 那天是6.14,今天7.18了 //然鹅我看着最前边缺失的模拟1,还是终于忍不住把它补上,为了保持顺序2345重新发布了一遍.. #   用  户  名   ...

  8. 2021.5.22 noip模拟1

    这场考试考得很烂 连暴力都没打好 只拿了25分,,,,,,,,好好总结 T1序列 A. 序列 题目描述 HZ每周一都要举行升旗仪式,国旗班会站成一整列整齐的向前行进. 郭神作为摄像师想要选取其中一段照 ...

  9. NOIP 模拟 $36\; \rm Cicada 拿衣服$

    题解 \(by\;zj\varphi\) 发现右端点固定时,左端点的 \(min-max\) 单调递减,且对于 \(or\) 和 \(and\) 相减,最多有 \(\rm2logn\)个不同的值,且相 ...

随机推荐

  1. hdu 2092 整数解(一元二次方程解)

    题目: 思路: 1.两个整数的和和积容易联想到一元二次方程的两个根,只要证明有两个解,并都是整数就打印出Yes,否则打印出No 2.最后判断那步,为什么只需要判断一个整数存在就够了,因为和是整数,一个 ...

  2. vue如何动态加载本地图片

    大家好,我是前端队长Daotin,想要获取更多前端精彩内容,关注我(全网同名),解锁前端成长新姿势. 以下正文: 今天遇到一个在vue文件中引入本地图片的问题,于是有了这篇文章. 通常,我们的一个im ...

  3. 公有云上构建云原生 AI 平台的探索与实践 - GOTC 技术论坛分享回顾

    7 月 9 日,GOTC 2021 全球开源技术峰会上海站与 WAIC 世界人工智能大会共同举办,峰会聚焦 AI 与云原生两大以开源驱动的前沿技术领域,邀请国家级研究机构与顶级互联网公司的一线技术专家 ...

  4. Linux 安装 Nodejs 的两种方式

    Linux 安装 Nodejs 的两种方式 目录 Linux 安装 Nodejs 的两种方式 一.压缩包安装 Nodejs 二.源码编译安装 Nodejs 一.压缩包安装 Nodejs 下载 Node ...

  5. POJ3190 - 优先队列 贪心

    POJ3190 将所有牛从小到大排序然后用优先队列(小根堆)依次记录插入的牛的结束时间,如果插入牛时起始时间大于首元素,ans不增加并弹出首元素. 挺简单的.那么为什么我会写(水)这篇博客呢? #in ...

  6. 《Node+MongoDB+React 项目实战开发》已出版

    前言 从深圳回长沙已经快4个月了,除了把车开熟练了外,并没有什么值得一提的,长沙这边要么就是连续下一个月雨,要么就是连续一个月高温暴晒,上班更是没啥子意思,长沙这边的公司和深圳落差挺大的,薪资也是断崖 ...

  7. spingsecurity 前后端分离跨域,ajax无用户信息

    1.自测时用的postman没有任何问题 2.和前端对接时发现登录不上,ajax Error 出错:{"readyState":0,"responseText" ...

  8. H5页面自动烟花特效

    代码如下: 1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> ...

  9. Blazor 路由及导航开发指南

    翻译自 Waqas Anwar 2021年4月2日的文章 <A Developer's Guide To Blazor Routing and Navigation> [1] 检查传入的请 ...

  10. django有什么CMS比较好用?哪个好?

    这个网站有目前在电子商务领域流行的django cms的横向对比表格,可以看看 https://djangopackages.org/grids/g/ecommerce/ 从结果上来看,django- ...