ZOJ 3963:Heap Partition(贪心+set+并查集)
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3963
题意:给出一个n个数的序列,可以在其中找一个子序列建堆,并且堆中的父亲结点j和孩子结点i满足sj ≤ si and j < i。问要分配所有的数到堆里面,最少可以建多少个堆。
思路:对于每一个数,如果前面有小于等于它的数并且那个数的左右孩子还没满,那么就可以放在它的下面。考虑最优情况,就应该是每次插入到左右孩子还没满的,并且小于等于当前枚举的数的最大的数,然后插入到这个数后面。
因此可以用set来保存结点,每次都二分查找一下,如果没找到就建新的堆,找到了就插在它后面。
可以用并查集来保存关系。
#include <bits/stdc++.h>
using namespace std;
#define N 100010
struct node {
int val, id, cnt;
bool operator < (const node &rhs) const {
if(rhs.val != val) return val < rhs.val;
if(rhs.id != id) return id > rhs.id; // 大的id优先,因为val相同的话,要使得二分可以返回val
return cnt > rhs.cnt;
}
};
int fa[N], a[N];
set<node> se;
vector<int> ans[N]; int Find(int x) { if(x == fa[x]) return x; return fa[x] = Find(fa[x]); } int main() {
int t; scanf("%d", &t);
while(t--) {
int n; scanf("%d", &n);
se.clear(); int k = ;
for(int i = ; i <= n; i++) scanf("%d", &a[i]), a[i] = -a[i], fa[i] = i;
for(int i = ; i <= n; i++) {
node now = (node) { a[i], i, };
set<node>::iterator it = se.lower_bound(now);
// lower_bound返回大于等于now的元素,设成负数,可以变成返回小于等于now的元素
if(it != se.end()) {
int x = it->val, y = it->id, z = it->cnt;
se.erase(it);
if(z - ) se.insert((node) {x, y, z - });
fa[i] = Find(y);
}
se.insert(now);
}
for(int i = ; i <= n; i++) if(fa[i] == i) ans[i].clear(), k++;
for(int i = ; i <= n; i++) ans[Find(i)].push_back(i);
printf("%d\n", k);
for(int i = ; i <= n; i++) {
if(fa[i] != i) continue;
printf("%d", ans[i].size());
for(int j = ; j < ans[i].size(); j++) printf(" %d", ans[i][j]);
puts("");
}
}
return ;
}
ZOJ 3963:Heap Partition(贪心+set+并查集)的更多相关文章
- zoj 3963 Heap Partition(并查集,贪心,二分)
Heap Partition Time Limit: 2 Seconds Memory Limit: 65536 KB Special Judge A sequence S = { ...
- ZOJ 3963 Heap Partition set维护。给一个序列,将其划分成尽量少的序列,使每一个序列满足按照顺序构造二叉树,父母的值<=孩子的值。
Heap Partition Time Limit: Seconds Memory Limit: KB Special Judge A sequence S = {s1, s2, ..., sn} i ...
- ZOJ 3963 Heap Partition(multiset + stl自带二分 + 贪心)题解
题意:给你n个数字s1~sn,要你把它们组成一棵棵二叉树,对这棵二叉树来说,所有节点来自S,并且父节点si<=子节点sj,并且i<j,问你树最少几棵二叉数.树 思路:贪心.我们往multi ...
- Luogu 1525 【NOIP2010】关押罪犯 (贪心,并查集)
Luogu 1525 [NOIP2010]关押罪犯 (贪心,并查集) Description S城现有两座监狱,一共关押着N名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨 ...
- zoj-3963 Heap Partition(贪心+二分+树状数组)
题目链接: Heap Partition Time Limit: 2 Seconds Memory Limit: 65536 KB Special Judge A sequence ...
- hdu 4424 & zoj 3659 Conquer a New Region (并查集 + 贪心)
Conquer a New Region Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...
- hdu 2480 贪心+简单并查集
Steal the Treasure Time Limit: 10000/6000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...
- POJ-1456 Supermarket(贪心,并查集优化)
Supermarket Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 10725 Accepted: 4688 Descript ...
- 1202. [HNOI2005]狡猾的商人【贪心 或 并查集】
Description 刁姹接到一个任务,为税务部门调查一位商人的账本,看看账本是不是伪造的.账本上记录了n个月以来的收入情况,其中第i 个月的收入额为Ai(i=1,2,3...n-1,n), .当 ...
随机推荐
- 关于JSON 字段数据的直接查询
最新的pgSQL 对json的支持在进一步加强!虽然我也学了那么点皮毛,但是json数据对于WEB的开发确实很重要,苦苦学习了很长一段时间,不断的关系PGSQL的动向! 好在翻看很多高人的例子和介绍, ...
- WPF数据模板的数据触发器的使用
<Window x:Class="CollectionBinding.MainWindow" xmlns="http://schemas.micros ...
- IDEA 问题 & 解决
# 问题 Error: java: Compilation failed: internal java compiler error # 解决 http://blog.csdn.net/u011275 ...
- PHP提取字符串中的图片地址
PHP提取字符串中的图片地址 $str='<p><img border="0" src="upfiles/2009/07/1246430143_1.jp ...
- Hive-分组之后取前n个
1. 统计国家每个省份出现次数最高的5个城市的名称 直观思维来考虑: 把 数据组织成: 国家 省份 出现次数(倒序) 城市 row_number() 根据partition by 生 ...
- java中==和equels的区别
起初接触java的时候这个问题还是比较迷茫的,最近上班之余刷博客的时候看了一些大神写的文章,自己也来总结一下,直接贴代码: package string; public class demo1 { p ...
- Win10《芒果TV》商店版更新v3.2.4:新增跨年事件直播、电视台直播,新年快乐
听说半个娱乐圈都来了,<芒果TV>UWP版邀您一起,于2016年12月31日晚,观看<湖南卫视2016·2017跨年演唱会>直播,请更新v3.2.4版,主要新增大事件直播和电视 ...
- Dec Working Note
01 新的一个月,也是16年最后一个月,意义非凡. 那么第一天就要来点非凡的意义:提出离职. 纠结了好久,最后还是离职了,感觉是好他妈的爽,纠结什么呢. 不过今天状态不好,最近状态一直不好,上火,也没 ...
- 毕设(一)C#的百度api调用
这个学期就要毕业了,选了一个无人机地面站软件设计的题目,这几天也开始着手做, 首先做了一个百度地图的调用,这里因为是上位机的开发,所有就不介绍Javascript的 调用方法,核心是用到一个类Http ...
- Delphi 导出数据至Excel的7种方法
一; delphi 快速导出excel uses ComObj,clipbrd; function ToExcel(sfilename:string; ADOQuery:TADOQuery):bool ...