zoj 3963 heap partion
https://vjudge.net/problem/ZOJ-3963
题意:
给出一个数列,可以用这个数列构造一种二叉树,这个二叉树满足数的下标 i <= j,并且 si <= sj,si是sj的父亲,问给出的数列可以构造多少棵这样的二叉树。
思路:
这题赛上没有写出来,看了题解之后给补的。
首先,通过这题学到了,memset初始化数组有时是会造成超时的。set的upper_bound(x)这个函数,它返回set中大于x的第一个元素的位置(注意是大于,不是大于等于)。
于是,这题就是贪心加set。贪心指的是对于当前的输入的x,在前面找到小于等于它的数,如果说没有找到,那么就把这个数插入,作为一棵新的树的根。如果说找到了,那么就把这个点插入这棵树,并且把这个数可插入的数量减1,当数量为0的时候就不能再插入了。具体看看注释。
代码:
#include <stdio.h>
#include <string.h>
#include <vector>
#include <set>
#include <algorithm>
using namespace std; int num,node[],cnt[];//node保存节点x的编号,cnt数组表示每个节点能插入的剩下的位置 vector<int> ans[];//ans保存答案
set<int> s; void solve(int x,int pos)
{
set<int>::iterator it; it = s.upper_bound(x); if (it == s.begin())//x是最小的,所以选择插入
{
s.insert(x); cnt[x] = ;//一开始有两个空位 node[x] = num; ans[node[x]].push_back(pos); num++;
}
else
{
--it;//因为是大于x的位置,所以要-- if (x == (*it))//相等,就不用插入,旧的元素
{ cnt[x]++;//相当于是加了2个位置,然后自己又占了一个 ans[node[x]].push_back(pos);
}
else
{
node[x] = node[*it]; cnt[*it]--; if (cnt[*it] == ) s.erase(*it);//没有位置了,删除 cnt[x] = ;//新的元素 s.insert(x);//后面插入是防止迭代器改变 ans[node[x]].push_back(pos);
}
}
}
int main()
{
int t; scanf("%d",&t); while (t--)
{ s.clear(); num = ; int n; scanf("%d",&n); for (int i = ;i <= n;i++)
{
node[i] = cnt[i] = ;
ans[i].clear();//说了n的总和不超过2 * 10 ^ 6,用memeset反而会超时
} for (int i = ;i <= n;i++)
{
int x; scanf("%d",&x); solve(x,i);
} printf("%d\n",num); for (int i = ;i < num;i++)
{
int sz = ans[i].size(); printf("%d",sz); for (int j = ;j < sz;j++)
{
printf(" %d",ans[i][j]);
} printf("\n");
}
} return ;
}
zoj 3963 heap partion的更多相关文章
- 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(并查集,贪心,二分)
Heap Partition Time Limit: 2 Seconds Memory Limit: 65536 KB Special Judge A sequence S = { ...
- ZOJ 3963 Heap Partition(multiset + stl自带二分 + 贪心)题解
题意:给你n个数字s1~sn,要你把它们组成一棵棵二叉树,对这棵二叉树来说,所有节点来自S,并且父节点si<=子节点sj,并且i<j,问你树最少几棵二叉数.树 思路:贪心.我们往multi ...
- Heap Partition ZOJ - 3963(贪心)
ZOJ - 3963 贪心做一下就好了 反正别用memset #include <iostream> #include <cstdio> #include <sstrea ...
- ZOJ 3963:Heap Partition(贪心+set+并查集)
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3963 题意:给出一个n个数的序列,可以在其中找一个子序列建堆,并且堆中的父 ...
- ZOJ - 2243 - Binary Search Heap Construction
先上题目: Binary Search Heap Construction Time Limit: 5 Seconds Memory Limit: 32768 KB Read the sta ...
- ZOJ 2334 Monkey King
并查集+左偏树.....合并的时候用左偏树,合并结束后吧父结点全部定成树的根节点,保证任意两个猴子都可以通过Find找到最厉害的猴子 Monkey King ...
- 左偏树(Leftist Heap/Tree)简介及代码
左偏树是一种常用的优先队列(堆)结构.与二叉堆相比,左偏树可以高效的实现两个堆的合并操作. 左偏树实现方便,编程复杂度低,而且有着不俗的效率表现. 它的一个常见应用就是与并查集结合使用.利用并查集确定 ...
- ZOJ 刷题记录 (。・ω・)ノ゙(Progress:31/50)
[热烈庆祝ZOJ回归] P1002:简单的DFS #include <cstdio> #include <cstring> #include <algorithm> ...
随机推荐
- Android开发的过去、现在和将来
现如今,拥有着 80% 的市场份额的 Android 是最主流的手机操作系统.它运行在无数的智能手机.平板以及其他各种各样的设备上.仅凭这一点,我们是否可以认为 Android 编程是简单而轻松的呢 ...
- 借用mysql 或者其他数据库 处理MSSQL 2016前处理导入特殊字符
MSSQL 2016支持了utf8编码的文件,之前处理比较麻烦的bcp 方式导入特殊字符一下子就方便了. 但是之前的版本,处理起来还是有一点麻烦.这次处理使用的数据库版本是sql server 201 ...
- Linux常见命令(二)
随着Linux应用的扩展许多同学开始接触Linux,根据学习Windwos的经验往往有一些茫然的感觉:不知从何处开始学起.虽然Linux桌面应用发展很快,但是命令在Linux中依然有很强的生命力.Li ...
- Dom 简介
HTML DOM 简介 DOM 教程 DOM 节点 HTML DOM 定义了访问和操作 HTML 文档的标准. 您应该具备的基础知识 在您继续学习之前,您需要对以下内容拥有基本的了解: HTML CS ...
- Vulkan Tutorial 18 重构交换链
操作系统:Windows8.1 显卡:Nivida GTX965M 开发工具:Visual Studio 2017 Introduction 现在我们已经成功的在屏幕上绘制出三角形,但是在某些情况下, ...
- ES 2015/6 新特性汇总
ES 2015/6 新特性汇总 箭头函数 箭头函数,通过 => 语法实现的函数简写形式,C#/JAVA8/CoffeeScript 中都有类似语法.与函数不同,箭头函数与其执行下文环境共享同一个 ...
- 我们为什么要使用AOP?
原文地址http://www.cnblogs.com/xrq730/p/7003082.html,转载请注明出处,谢谢 前言 一年半前写了一篇文章Spring3:AOP,是当时学习如何使用Spring ...
- php访问数据库$result=$mysql_qurey('')判断是否是空值
在访问数据库后得到result值,前提是$relust为true,就是没有发生错误连接情况,但是查询的条件由于不满足导致返回值为空,此时判断就不能用!来决定是否有返回数据了,经过书籍搜索,用resul ...
- SICIP-1.3-Defining a new function
定义函数 def <name> (former parament): 函数体(缩进) 环境 全局环境 局部环境 只在函数内部有效 TIP 函数体只在调用的最后执行 抽象化函数 函数域(函数 ...
- 添加保存less报错
编辑器在添加保存less文件弹出一下错误: re-evaluation native module sources is not supported,if you are using the grac ...