bzoj4345 POI2016 Korale

题目链接https://lydsy.com/JudgeOnline/problem.php?id=4345

数据范围:略。


题解

由于$k$的范围问题,我们很容易想到优先队列。

至于从每个状态怎么往下一个转移就是这个题的精髓。

我们先考虑第一问:

第一问没有字典序的限制,我们把所有的数按照从小到大排序。

堆里维护二元组$(Sum, id)$表示这种选取方式的和位$Sum$,最大下标为$id$。

它可以转移到$(Sum - a_{id} + a_{id+1}, id+1)$和$(Sum + a_{id + 1}, id + 1)$。

这一想是显然的,但是不咋好想...有点超级钢琴的味道。

下面我们考虑第二问:

第二问我们爆搜即可,想求出来当前下标(不排序)到最后一个数这个区间内,小于当前剩余和的最小下标的数是啥,然后暴力搜下去即可。

这个过程可以用线段树维护。

至于复杂度为什么是对的?因为我们每时每刻都保证了所有的枚举和都是小于第一问的值的,即使枚举到了第一问的值也在接受范围内。

言外之意我们枚举的每一个值,都是前$k-1$中的一个。

代码

#include <bits/stdc++.h>

#define ls p << 1 

#define rs p << 1 | 1 

#define N 1000010 

using namespace std;

typedef long long ll;

char *p1, *p2, buf[100000];

#define nc() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1 ++ )

int rd() {
int x = 0;
char c = nc();
while (c < 48) {
c = nc();
}
while (c > 47) {
x = (((x << 2) + x) << 1) + (c ^ 48), c = nc();
}
return x;
} priority_queue <pair<ll, int> > q; int a[N], b[N], Same, mn[N << 2]; ll ans[N]; inline void pushup(int p) {
mn[p] = min(mn[ls], mn[rs]);
} void build(int l, int r, int p) {
if (l == r) {
mn[p] = b[l];
return;
}
int mid = (l + r) >> 1;
build(l, mid, ls), build(mid + 1, r, rs);
pushup(p);
} int query(int x, ll y, int l, int r, int p) {
if (x <= l) {
if (mn[p] > y) {
return 0;
}
if (l == r) {
return l;
}
}
int mid = (l + r) >> 1;
if (x <= mid) {
int mdl = query(x, y, l, mid, ls);
if (mdl) {
return mdl;
}
}
return query(x, y, mid + 1, r, rs);
} int top, st[N], n, k; void dfs(int p, ll re) {
if (!Same) {
return;
}
if (!re) {
Same -- ;
if (!Same) {
for (int i = 1; i <= top; i ++ ) {
printf("%d ", st[i]);
}
puts("");
}
return;
}
for (int i = p + 1; i <= n; i ++ ) {
i = query(i, re, 1, n, 1);
if (i) {
st[ ++ top] = i;
dfs(i, re - b[i]);
top -- ;
}
else {
break;
}
}
} int main() {
n = rd(), k = rd() - 1;
for (int i = 1; i <= n; i ++ ) {
a[i] = b[i] = rd();
}
sort(a + 1, a + n + 1);
q.push(make_pair(-a[1], 1));
for (int i = 1; i <= k; i ++ ) {
ans[i] = -q.top().first;
int x = q.top().second;
q.pop();
if (x < n) {
q.push(make_pair(-(ans[i] - a[x] + a[x + 1]), x + 1));
q.push(make_pair(-(ans[i] + a[x + 1]), x + 1));
}
}
// for (int i = 1; i <= k; i ++ ) {
// printf("%lld ", ans[i]);
// }
// puts("");
cout << ans[k] << endl ;
for (int i = k; i; i -- ) {
if (ans[i] != ans[k]) {
break;
}
Same ++ ;
}
// cout << Same << endl ;
build(1, n, 1);
dfs(0, ans[k]);
return 0;
}

[bzoj4345][POI2016]Korale_堆_贪心_线段树_dfs的更多相关文章

  1. BZOJ_2161_布娃娃_权值线段树

    BZOJ_2161_布娃娃_权值线段树 Description 小时候的雨荨非常听话,是父母眼中的好孩子.在学校是老师的左右手,同学的好榜样.后来她成为艾利斯顿第二 代考神,这和小时候培养的良好素质是 ...

  2. BZOJ_3685_普通van Emde Boas树_权值线段树

    BZOJ_3685_普通van Emde Boas树_权值线段树 Description 设计数据结构支持: 1 x  若x不存在,插入x 2 x  若x存在,删除x 3    输出当前最小值,若不存 ...

  3. B20J_2733_[HNOI2012]永无乡_权值线段树合并

    B20J_2733_[HNOI2012]永无乡_权值线段树合并 Description:n座岛,编号从1到n,每座岛都有自己的独一无二的重要度,按照重要度可以将这n座岛排名,名次用1到 n来表示.某些 ...

  4. BZOJ_1503_[NOI2004]郁闷的出纳员_权值线段树

    BZOJ_1503_[NOI2004]郁闷的出纳员_权值线段树 Description OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的 工资. ...

  5. BZOJ_1012_[JSOI2008]_最大数maxnumber_(线段树/树状数组+RMQ)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1012 两种操作: 1.求序列末尾n个数中的最大值. 2.在序列末尾插入一个数. 分析 线段树求 ...

  6. [bzoj2733][HNOI2012]永无乡_权值线段树_线段树合并

    永无乡 bzoj-2733 HNOI-2012 题目大意:题目链接. 注释:略. 想法: 它的查询操作非常友善,就是一个联通块内的$k$小值. 故此我们可以考虑每个联通块建一棵权值线段树. 这样的话每 ...

  7. [jdoj1258]野生动物园(change by panxf)_权值线段树_组合数

    人品计算 题目大意:n个数的a序列,m组询问.每次询问给出T,A,B,K.求在a序列的[A,B]的位置之内的K小值P,的$C_{T}^{P \% T} \% 10111$. 注释:每组询问保证区间只相 ...

  8. 3065: 带插入区间K小值_树套树_替罪羊树_权值线段树

    经过周六一天,周一3个小时的晚自习,周二2个小时的疯狂debug,终于凭借自己切掉了这道树套树题. Code: #include <cstdio> #include <algorit ...

  9. 【Luogu1973】仓配置(贪心,线段树)

    [Luogu1973]仓配置 题面 直接找洛谷把... 题解 很明显的贪心吧 按照线段的右端点为第一关键字,左端点第二关键字排序 然后线段树维护区间最小就可以啦 #include<iostrea ...

随机推荐

  1. (27)打鸡儿教你Vue.js

    v-for 数组参数的顺序 当含有index时,以前传递的参数顺序是: (index, value).现在(value, index) ready替换使用新的mounted钩子代替,通过使用mount ...

  2. (2)Go基本数据类型

    Go语言的基本类型有: bool string int.int8.int16.int32.int64 uint.uint8.uint16.uint32.uint64.uintptr byte // u ...

  3. Android中相对布局的两个控件

    <Button android:id="@+id/button3" android:layout_width="wrap_content" android ...

  4. 【2019.10.30】SDN上机第1次作业

    用字符命令搭建如下拓扑,要求写出命令 题目一: 字符命令如下: 题目二: 字符命令如下: 利用可视化工具搭建如下拓扑 要求支持OpenFlow 1.0 1.1 1.2 1.3,设置h1(10.0.0. ...

  5. jQuery学习笔记——基本了解

    安装 两种方法: 从 jquery.com 下载jQuery. 从 CDN 中载入 jQuery, 如从我的博客中加载 jQuery: <script src="https://blo ...

  6. CRMEB中因为重写规则导致的服务器异常和404之解决办法

    问题描述:安装CRMEB后,只能通过https://域名//index.php/admin访问到后台,而不能直接通过https://域名/admin访问到后台,以至于导致进入系统后台出现有的功能界面可 ...

  7. 蚂蚁金服财富技术部,诚招Java研发工程师。校招内推!!!

    蚂蚁金服财富技术部,诚招Java研发工程师. 团队是蚂蚁金服财富技术部核心团队,支持亿级互联网交易清算,在这里不仅能学习到先进的互联网技术,也能了解许多终身受益的金融知识. 内推对象 2020届毕业生 ...

  8. Windows 实例远程桌面报错“没有远程桌面授权服务器可以提供许可证”

    参考阿里云帮助文档: https://help.aliyun.com/knowledge_detail/40859.html?spm=5176.10695662.1996646101.searchcl ...

  9. 将WSL2作为生产力工具

    适用于 Linux 的 Windows 子系统 (WSL) 是 Windows 10新增的功能,使用它可以直接在 Windows 上运行 Linux 命令.而WSL 2 是WSL的一个新版本,它支持适 ...

  10. 查看 systemctl 崩溃日志 及 运行日志

    vi /var/log/syslog 查看指定服务的: grep "bx" /var/log/syslog