CCPC-Wannafly Winter Camp Day1 Div1 - 夺宝奇兵 - [贪心+线段树]
题目链接:https://zhixincode.com/contest/3/problem/J?problem_id=43


样例输入 1
4 11
10 1
1 1
10 2
1 2
10 3
1 3
15 4
15 4
15 4
15 4
15 4
样例输出 1
28
题解:
首先是有个简单的想法,假设wls买完后,$n$ 个居民他们的各自的宝物数目最大不超过 $k$,因此wls手里的宝物数目至少要大于 $k$。
所以暴力枚举 $k$,然后再暴力地对所有宝物数目超过 $k$ 的居民,将他们买到不超过 $k$;然后如果此时wls手里的宝物数 $\leq k$ 则再从所有居民的宝物中挑最便宜的买,直到wls的宝物数目大于 $k$ 为止(假设要再买 $e$ 个宝物才行)。
如果是div2的话,由于 $n,m$ 范围小,想到这里就可以直接写了,div1的话还需要考虑优化。
我们知道,如果把居民按宝物数目从大到小排序,并且每个居民的宝物按价值排序(小的放在上面),那么从大到小枚举 $k$ 的时候,就像一把刀一层层的往下压,那么每个居民的宝物局如同一个不规则的楼梯上一层层的被削去,由于宝物数目最多 $m$ 个,因此把这些宝物一点点收入wls的囊中只需要 $O(m)$ 的时间复杂度。
那么,再考虑怎么从居民手里还剩的宝物中,再买 $e$ 个宝物以使wls的宝物数最多,可以用线段树来做,每次已经确定收入wls囊中的宝物都在线段树中标成 $0$,然后在线段树中用数量 $e$ 去查询得到相应的花费。最后维护每个 $k$ 对应的wls总花费的最小值即可。
这样一来,时间复杂度就是 $O(m \log m)$ 的,就不会超时了。
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll,int> P;
#define val(p) (p.first)
#define idx(p) (p.second)
#define mk(x,y) make_pair(x,y)
const ll INF=1e16;
const int maxn=1e5+, maxm=1e5+; int n,m;
vector<P> peo[maxn]; //按居民存储宝物
int rk[maxn]; //按宝物数目存储居民编号
bool cmp(int a,int b) {
return peo[a].size()>peo[b].size();
} P tre[maxm]; //存储所有宝物并排序,并构建相应的线段树
int pos[maxm]; //指出宝物在线段树中的位置 #define ls (rt<<1)
#define rs (rt<<1|1)
struct Node{
int l,r;
ll v; int c;
}o[maxm<<];
void pushup(int rt)
{
o[rt].v=o[ls].v+o[rs].v;
o[rt].c=o[ls].c+o[rs].c;
}
void build(int rt,int l,int r)
{
o[rt].l=l, o[rt].r=r;
if(l==r)
{
o[rt].v=val(tre[l]), o[rt].c=;
return;
}
int mid=(l+r)>>;
build(ls,l,mid), build(rs,mid+,r);
pushup(rt);
}
void update(int rt,int pos)
{
if(o[rt].l==o[rt].r)
{
o[rt].v=, o[rt].c=;
return;
}
int mid=(o[rt].l+o[rt].r)>>;
pos<=mid?update(ls,pos):update(rs,pos);
pushup(rt);
}
ll query(int rt,int k)
{
if(o[rt].l==o[rt].r) return o[rt].v;
if(o[ls].c>=k) return query(ls,k);
else return o[ls].v+query(rs,k-o[ls].c);
} int main()
{
ios::sync_with_stdio();
cin.tie(), cout.tie(); cin>>n>>m;
for(int i=;i<=n;i++) peo[i].clear();
for(int i=;i<=m;i++)
{
ll a; int c; cin>>a>>c;
peo[c].push_back(tre[i]=mk(a,i));
}
for(int i=;i<=n;i++) sort(peo[i].begin(),peo[i].end(),greater<P>());
for(int i=;i<=n;i++) rk[i]=i; sort(rk+,rk+n+,cmp); sort(tre+,tre+m+);
for(int i=;i<=m;i++) pos[idx(tre[i])]=i; //根据原编号得到在线段树中的位置
build(,,m); int ed=;
ll ans=INF;
int acc_tot=; ll acc_cost=;
for(int k=peo[rk[]].size();k>=;k--)
{
for(;ed<=n && peo[rk[ed]].size()>k;ed++);
for(int i=;i<ed;i++)
{
while(peo[rk[i]].size()>k)
{
acc_cost+=val(peo[rk[i]].back());
acc_tot++;
update(,pos[idx(peo[rk[i]].back())]);
peo[rk[i]].pop_back();
}
} ll cost; //wls的总花费
if(acc_tot<=k) cost=acc_cost+query(,min(m,k+-acc_tot));
else cost=acc_cost; ans=min(ans,cost);
}
cout<<ans<<endl;
}
CCPC-Wannafly Winter Camp Day1 Div1 - 夺宝奇兵 - [贪心+线段树]的更多相关文章
- CCPC-Wannafly Winter Camp Day4 Div1 - 夺宝奇兵 - [简单思维题]
题目链接:https://zhixincode.com/contest/18/problem/A?problem_id=259 题目描述 wls正在玩一个寻宝游戏. 宝藏一共有 $n$ 种,都藏在一个 ...
- 2020 CCPC Wannafly Winter Camp Day1 C. 染色图
2020 CCPC Wannafly Winter Camp Day1 C. 染色图 定义一张无向图 G=⟨V,E⟩ 是 k 可染色的当且仅当存在函数 f:V↦{1,2,⋯,k} 满足对于 G 中的任 ...
- 2020 CCPC Wannafly Winter Camp Day1 Div.1& F
#include<bits/stdc++.h> #define forn(i, n) for (int i = 0; i < int(n); i++) #define fore(i, ...
- 2020 CCPC Wannafly Winter Camp Day1 - I. K小数查询(分块)
题目链接:K小数查询 题意:给你一个长度为$n$序列$A$,有$m$个操作,操作分为两种: 输入$x,y,c$,表示对$i\in[x,y] $,令$A_{i}=min(A_{i},c)$ 输入$x,y ...
- Wannafly Winter Camp Day8(Div1,onsite) E题 Souls-like Game 线段树 矩阵乘法
目录 Catalog Solution: (有任何问题欢迎留言或私聊 && 欢迎交流讨论哦 Catalog @ Problem:传送门 Portal 原题目描述在最下面. 简单的 ...
- CCPC-Wannafly Winter Camp Day1 Div1 - 爬爬爬山 - [最短路][堆优化dijkstra]
题目链接:https://zhixincode.com/contest/3/problem/F?problem_id=39 样例输入 1 4 5 1 1 2 3 4 1 2 1 1 3 1 1 4 ...
- CCPC Wannafly Winter Camp Div2 部分题解
Day 1, Div 2, Prob. B - 吃豆豆 题目大意 wls有一个\(n\)行\(m\)列的棋盘,对于第\(i\)行第\(j\)列的格子,每过\(T[i][j]\)秒会在上面出现一个糖果, ...
- Wannafly Winter Camp Day5 Div1 E题 Fast Kronecker Transform 转化为NTT或FFT
目录 Catalog Solution: (有任何问题欢迎留言或私聊 && 欢迎交流讨论哦 Catalog @ Problem:传送门 原题目描述在最下面. 对给定的式子算解. ...
- 2020 CCPC Wannafly Winter Camp Day2-K-破忒头的匿名信
题目传送门 sol:先通过AC自动机构建字典,用$dp[i]$表示长串前$i$位的最小代价,若有一个单词$s$是长串的前$i$项的后缀,那么可以用$dp[i - len(s)] + val(s)$转移 ...
随机推荐
- 让 Python 更加充分的使用 Sqlite3
我最近在涉及大量数据处理的项目中频繁使用 sqlite3.我最初的尝试根本不涉及任何数据库,所有的数据都将保存在内存中,包括字典查找.迭代和条件等查询.这很好,但可以放入内存的只有那么多,并且将数据从 ...
- 基于Ubuntu + nextCloud 搭建自己的私人网盘
系统要求:Ubuntu 16.04.1 LTS 64 位操作系统 基础设置 切换为 root 账号 Ubutu 系统默认登录的用户为非 root 权限用户,为了能正常安装 nextCloud,需要切换 ...
- android 获得View的高度
在一个activity中有一个textview,设置字数不同,如何能在打开这个activity时就及时获得这个textview在activity的高度,有利于我对textview的高度进行设置. ...
- android的左右滑动效果实现-ViewFlipper
说到android的左右滑动效果我们可以说是在每个应用上面都可以看到这样的效果,不管是微博,还是QQ等.实现左右滑动的方式很多,有ViewPaer(不过这个和需要android-support-v4. ...
- 使用SharedPreference和对象流存储对象
编写PreferencesUtils工具类可以简单对象(可以缓存对象中所有public的简单属性) 另外研究了Preference存储与直接采用对象文件缓存方式的区别 第一次写文件时 1.效率,直 ...
- Centos7.x 执行top命令教程
一.作用 top命令用来显示执行中的进程,使用权限是所有用户 二.格式 top [-] [d delay] [q] [c] [S] [s] [i] [n] 三.命令参数解释 d:指定更新的间隔,以秒计 ...
- cbow与skip-gram
场景:上次回答word2vec相关的问题,回答的是先验概率和后验概率,没有回答到关键点. 词袋模型(Bag of Words, BOW)与词向量(Word Embedding)模型 词袋模型就是将句子 ...
- ASP.NET IIS Registration Tool (Aspnet_regiis.exe)
IIS Version Special cases for 32-bit versions of Aspnet_regiis.exe 6.0 You can run the 32-bit versio ...
- Java SpringBoot中使用sqljdbc4注意事项 java.lang.ClassNotFoundException: com.microsoft.sqlserver.jdbc.SQLServerDriver
因项目需要,需要在Java项目中访问 MSSQLServer 数据库,本地开发的时候,没有问题,可以正常链接数据库,通过Jenkins部署到服务器上时候,报数据库驱动未找到. java.lang.Cl ...
- DOS、Mac 和 Unix 文件格式+ UltraEdit使用
文件格式 区分DOS.Mac 和 Unix分别对应三种系统 从文件编码的方式来看,文件可分为ASCII码文件和二进制码文件两种 文件模式 区分ASCII模式和Binary模式 通常由系统决定,大多数 ...