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+并查集)的更多相关文章

  1. zoj 3963 Heap Partition(并查集,贪心,二分)

    Heap Partition Time Limit: 2 Seconds      Memory Limit: 65536 KB      Special Judge A sequence S = { ...

  2. ZOJ 3963 Heap Partition set维护。给一个序列,将其划分成尽量少的序列,使每一个序列满足按照顺序构造二叉树,父母的值<=孩子的值。

    Heap Partition Time Limit: Seconds Memory Limit: KB Special Judge A sequence S = {s1, s2, ..., sn} i ...

  3. ZOJ 3963 Heap Partition(multiset + stl自带二分 + 贪心)题解

    题意:给你n个数字s1~sn,要你把它们组成一棵棵二叉树,对这棵二叉树来说,所有节点来自S,并且父节点si<=子节点sj,并且i<j,问你树最少几棵二叉数.树 思路:贪心.我们往multi ...

  4. Luogu 1525 【NOIP2010】关押罪犯 (贪心,并查集)

    Luogu 1525 [NOIP2010]关押罪犯 (贪心,并查集) Description S城现有两座监狱,一共关押着N名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨 ...

  5. zoj-3963 Heap Partition(贪心+二分+树状数组)

    题目链接: Heap Partition Time Limit: 2 Seconds      Memory Limit: 65536 KB      Special Judge A sequence ...

  6. 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 ...

  7. hdu 2480 贪心+简单并查集

    Steal the Treasure Time Limit: 10000/6000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  8. POJ-1456 Supermarket(贪心,并查集优化)

    Supermarket Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 10725 Accepted: 4688 Descript ...

  9. 1202. [HNOI2005]狡猾的商人【贪心 或 并查集】

    Description 刁姹接到一个任务,为税务部门调查一位商人的账本,看看账本是不是伪造的.账本上记录了n个月以来的收入情况,其中第i 个月的收入额为Ai(i=1,2,3...n-1,n), .当 ...

随机推荐

  1. MySql 5.7 重置root密码

    一.以安全模式登录 # Stop MySQL sudo service mysql stop # Make MySQL service directory. sudo mkdir -p /var/ru ...

  2. QT 等待对话框/进度--

    用QT的,加载的一张gif图片.记录下来以后免得忘记. #ifndef DIALOG_H #define DIALOG_H #include <QDialog> #include < ...

  3. MVC WebApi的两种访问方法

    //UserInfoController using ClassLibrary; using System;using System.Collections.Generic;using System. ...

  4. byte[] 左移和右移

    public static class ex { public static byte[] RightShift(this byte[] ba, int n) { ) { return ba.Left ...

  5. php将秒转换为 分:秒 函数

    php将秒转换为 分:秒 函数 /** * 将秒转换为 分:秒 * s int 秒数 */ function s_to_hs($s=0){ //计算分钟 //算法:将秒数除以60,然后下舍入,既得到分 ...

  6. 人像美妆---妆容迁移算法研究(Makeup transfer)

    原文:人像美妆---妆容迁移算法研究(Makeup transfer) 对于人像美妆算法,现在的美妆相机.玩美彩妆之类的app已经做的比较成熟了,但是具体算法,基本网络上是杳无可查,今天本人介绍一种自 ...

  7. 了解BroadcastRecever

    广播分类: 标准广播(Normal broadcasts):完全异步执行的广播,接收没有先后顺序,效率高,无法被接收器被拦截. 有序广播(Ordered broadcasts) :同步执行的广播,有先 ...

  8. Python:Pandas学习

    import pandas as pd import numpy as np s = pd.Series([1, 3, 6, np.nan, 44, 1]) df= pd.DataFrame(np.r ...

  9. Delphi 7.0常用函数速查手册(磁盘文件类)

    在Delphi 7.0中,已为我们定义好了非常多的函数,大致分类有6种:数据类型转换函数.字符串.数组操作函数.文件.磁盘操作函数.内存.指针操作函数.数学运算函数.日期函数. 在Delphi中调用函 ...

  10. centos yum 安装 jdk1.8

    JDK: 版本:1.8 服务器默认安装1.7,所以不使用默认安装 yum -y list java* --查看yum的jdk安装包 yum install java-1.8.0-openjdk jav ...