ZOJ 3963 Heap Partition set维护。给一个序列,将其划分成尽量少的序列,使每一个序列满足按照顺序构造二叉树,父母的值<=孩子的值。
Heap Partition
Time Limit: Seconds Memory Limit: KB Special Judge A sequence S = {s1, s2, ..., sn} is called heapable if there exists a binary tree T with n nodes such that every node is labelled with exactly one element from the sequence S, and for every non-root node si and its parent sj, sj ≤ si and j < i hold. Each element in sequence S can be used to label a node in tree T only once. Chiaki has a sequence a1, a2, ..., an, she would like to decompose it into a minimum number of heapable subsequences. Note that a subsequence is a sequence that can be derived from another sequence by deleting some elements without changing the order of the remaining elements.
Input There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case: The first line contain an integer n ( ≤ n ≤ ) — the length of the sequence. The second line contains n integers a1, a2, ..., an ( ≤ ai ≤ n). It is guaranteed that the sum of all n does not exceed × .
Output For each test case, output an integer m denoting the minimum number of heapable subsequences in the first line. For the next m lines, first output an integer Ci, indicating the length of the subsequence. Then output Ci integers Pi1, Pi2, ..., PiCi in increasing order on the same line, where Pij means the index of the j-th element of the i-th subsequence in the original sequence.
Sample Input Sample Output Hint
Author: LIN, Xi
Source: The 14th Zhejiang Provincial Collegiate Programming Contest Sponsored by TuSimple /**
题目:Heap Partition
链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5595
题意:给一个序列,将其划分成尽量少的序列,使每一个序列满足按照顺序构造二叉树,父母的值<=孩子的值。
思路:对初始序列讨论,如果某个值a[i],位置为i;要插入到别的二叉树上,那么就要在前面找一个a[j]<=a[i]且孩子少于两个的最接近a[i]的值a[j],位置为j。
那么j的孩子加一。 如果j的孩子有两个,那么以后不能再让别人成为它的孩子。如果找不到,那么i这个位置的值作为一颗新的二叉树的根。
我们要维护value,所属二叉树编号,该节点的孩子数。所以用一个set来维护。具体需要注意地方看下面反思。 反思:当时我没有做出来,没有考虑到set把重复的给去掉了。我一直以为set是按照内容来判重的。
原来是通过排序规则来判重(我傻了),所以如果排序规则只判断了return value<k.value;
那么只要value=k.value;这个就会被判重去掉。哪怕cnt,value,last不同。
解决这种问题,要么用multiset;要么set的排序规则所有情况都排一下序,为了保证唯一,所以新增一个id表示这个值在初始序列的下标位置。
*/ #include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<set>
#include<cmath>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const int inf = 0x3f3f3f3f;
const int maxn = 1e5+;
struct node
{
int value;
int cnt;
int last;
node(){}
node(int v,int c,int l):value(v),cnt(c),last(l){}
bool operator < (const node&k) const{
return value<k.value;
}
}t;
vector<int> v[maxn];
multiset<node>se;
int a[maxn];
int main()
{
int T, n;
cin>>T;
while(T--)
{
scanf("%d",&n);
for(int i = ; i<n; i++){
scanf("%d",&a[i]);
}
se.clear();
for(int i = ; i <= n; i++){
v[i].clear();
}
int ans = ;
t.value = a[];
t.cnt = ;
t.last = ;
se.insert(t);
ans = ;
v[t.last].push_back();
multiset<node>::iterator it;
for(int i = ; i < n; i++){
t.value = a[i];
it = se.upper_bound(t);
if(it==se.begin()){
t.cnt = ;
t.last = i;
t.value = a[i];
se.insert(t);
v[i].push_back(i);
ans++;
}else
{
it--;
t = *it;
t.cnt++;
se.erase(it);
if(t.cnt<){
se.insert(t);
}
t.value = a[i];
t.cnt = ;
v[t.last].push_back(i);
se.insert(t);
} }
printf("%d\n",ans);
for(int i = ; i < n; i++){
int len = v[i].size();
if(len==) continue;
printf("%d",len);
for(int j = ; j < len; j++){
printf(" %d",v[i][j]+);
}
printf("\n");
}
}
return ;
}
/*
struct node
{
int id;
int value;
int cnt;
int last;
node(){}
node(int i,int v,int c,int l):id(i),value(v),cnt(c),last(l){}
bool operator < (const node&k) const{
if(value!=k.value) return value<k.value;
if(cnt!=k.cnt) return cnt<k.cnt;
if(last!=k.last) return last<k.last;
return id<k.id;
}
}t;
vector<int> v[maxn];
set<node>se;
int a[maxn];
int main()
{
int T, n;
cin>>T;
while(T--)
{
scanf("%d",&n);
for(int i = 0; i<n; i++){
scanf("%d",&a[i]);
}
se.clear();
for(int i = 0; i <= n; i++){
v[i].clear();
}
int ans = 0;
t.value = a[0];
t.cnt = 0;
t.last = 0;
t.id = 0;
se.insert(t);
ans = 1;
v[t.last].push_back(0);
set<node>::iterator it;
for(int i = 1; i < n; i++){
t.value = a[i];
t.id = inf;
t.last = inf;
t.cnt = inf;
it = se.upper_bound(t);
if(it==se.begin()){
t.cnt = 0;
t.last = i;
t.value = a[i];
t.id = i;
se.insert(t);
v[i].push_back(i);
ans++;
}else
{
it--;
t = *it;
t.cnt++;
se.erase(it);
if(t.cnt<2){
se.insert(t);
}
t.id = i;
t.value = a[i];
t.cnt = 0;
v[t.last].push_back(i);
se.insert(t);
} }
printf("%d\n",ans);
for(int i = 0; i < n; i++){
int len = v[i].size();
if(len==0) continue;
printf("%d",len);
for(int j = 0; j < len; j++){
printf(" %d",v[i][j]+1);
}
printf("\n");
}
}
return 0;
}
*/
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(multiset + stl自带二分 + 贪心)题解
题意:给你n个数字s1~sn,要你把它们组成一棵棵二叉树,对这棵二叉树来说,所有节点来自S,并且父节点si<=子节点sj,并且i<j,问你树最少几棵二叉数.树 思路:贪心.我们往multi ...
- zoj 3963 heap partion
https://vjudge.net/problem/ZOJ-3963 题意: 给出一个数列,可以用这个数列构造一种二叉树,这个二叉树满足数的下标 i <= j,并且 si <= sj,s ...
- Heap Partition ZOJ - 3963(贪心)
ZOJ - 3963 贪心做一下就好了 反正别用memset #include <iostream> #include <cstdio> #include <sstrea ...
- zoj-3963 Heap Partition(贪心+二分+树状数组)
题目链接: Heap Partition Time Limit: 2 Seconds Memory Limit: 65536 KB Special Judge A sequence ...
- 调试台自动多出现一个'' ,我 用uploadify上传图片时,在给页面写入一个返回值为图片名称的变量的值的时候值的前面始终多出现一个''
对你有助请点赞,请顶,不好请踩------送人玫瑰,手留余香! 15:54 2016/3/12用uploadify上传图片时,在给页面写入一个返回值为图片名称的变量的值的时候值的前面始终多出现一个' ...
- Oracle新表使用序列(sequence)作为插入值,初始值不是第一个,oraclesequence
Oracle新表使用序列(sequence)作为插入值,初始值不是第一个,oraclesequence 使用oracle11g插入数据时遇到这样一个问题: 1 --创建测试表-- 2 CREATE T ...
- 有N个正实数(注意是实数,大小升序排列) x1 , x2 ... xN,另有一个实数M。 需要选出若干个x,使这几个x的和与 M 最接近。 请描述实现算法,并指出算法复杂度
题目:有N个正实数(注意是实数,大小升序排列) x1 , x2 ... xN,另有一个实数M. 需要选出若干个x,使这几个x的和与 M 最接近. 请描述实现算法,并指出算法复杂度. 代码如下: #in ...
- 【C语言】在两个数成对出现的数组中找到一个单独的数。
//在两个数成对出现的数组中找到一个单独的数.比如{1,2,3.3,1,4.2},即找出4 #include <stdio.h> int find(int arr[], int len) ...
随机推荐
- jvm-监控指令-jdump
格式: jmap [option] vmid 作用: 生成堆转储快照. 使用:(注意:需要使用工具打开,分析. 比如: EclipseMemoryAnalyzer)
- IIS 日志
查看工具: Log Parser + Log Parser Studio http://www.microsoft.com/en-us/download/details.aspx?displaylan ...
- scrapy安装使用教程
1. 安装Python,我用的是Python2.7.11,你喜欢用什么版本,你开心就好,只是后面的软件有些可能需要配套. 2. 安装pip,下载pip-8.1.2.tar.gz (md5, pgp). ...
- phpmyadmin后台4种拿shell方法 && php爆路径大法
php后台拿shell要知道php的路径,文章下面将讲诉爆php路径的方法!!! 方法一: CREATE TABLE `mysql`.`xss` (`xss1` TEXT NOT NULL ); IN ...
- Python3环境安装PySpider爬虫框架过程
收录待用,修改转载已取得腾讯云授权 大家好,本篇文章为大家讲解腾讯云主机上PySpider爬虫框架的安装. 首先,在此附上项目的地址,以及官方文档 PySpider 官方文档 安装流程 pip 首先确 ...
- Hyper-V Tools for win7
http://download.microsoft.com/download/C/1/C/C1CA233D-CA1A-4C4D-8240-B4AFC0FD3433/Windows6.1-KB95883 ...
- wifi破解到局域网渗透
本文转自 _博客 一,密码破解 wifi破解最主要的还是抓握手包破解(不要给我说某某钥匙的“分享”). wifi认证主要分为四步: 1,无线客户端与ap连接时,首先发送一个认证请求包 2,ap收到请求 ...
- Jquery DataTables 自定义布局sdom
Jquery DataTables 自定义布局sdom JQuery Datatable sDom 配置 官网给的描述是: This initialisation variable allows yo ...
- 微信小程序 - 更改button状态
wxml <button class='yes-orders' style='{{status_css}}' bindtap='clickExpress'> {{statusOrders} ...
- POJ 2942 Knights of the Round Table 黑白着色+点双连通分量
题目来源:POJ 2942 Knights of the Round Table 题意:统计多个个骑士不能參加随意一场会议 每场会议必须至少三个人 排成一个圈 而且相邻的人不能有矛盾 题目给出若干个条 ...