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) ...
随机推荐
- Bean的装配方式
(一) 知识点:Spring容器支持多种形式的Bean的装配方式,比如基于XML的装配,基于注解的装配和自动装配(最常用的就是基于注解的装配) Spring提供了两种基于xml的装配方式:设值注入(S ...
- FrameLayout 布局
(一) 1.效果图:颜色一直在改变,实现霓虹灯的效果 2.activity_main.xml <?xml version="1.0" encoding="utf-8 ...
- HDU 1402 A * B Problem Plus (FFT求高精度乘法)
A * B Problem Plus Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Other ...
- Google开源C++单元测试框架Google Test
1.玩转Google开源C++单元测试框架Google Test系列(gtest)之一 - 初识gtest 2.玩转Google开源C++单元测试框架Google Test系列(gtest)之二 - ...
- 用 JavaScript 检测浏览器在线/离线状态(JavaScript API — navigator.onLine)
如今HTML5 移动应用或 Web app 中越来越普遍的使用了离线浏览技术,所以用 JavaScript 检测浏览器在线/离线状态非常常见. 无论浏览器是否在线,navigator.onLine 属 ...
- Anaconda 介绍及安装
一.前言 Python易用,但用好却不易,其中比较头疼的就是包管理和Python不同版本的问题,特别是当你使用Windows的时候.为了解决这些问题,有不少发行版的Python,比如WinPython ...
- yii2 URL重写 nginx的配置
Url的重写 nginx的配置文件 [root@localhost protected]# vim /etc/nginx/conf.d/default.conf server { listen ...
- javascript http库axios
还是那个开源项目中的代码看到的: 直接看axios官方的介绍吧,里面的用法介绍很全: https://github.com/mzabriskie/axios Installing Using npm: ...
- testform
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- [React] Return a list of elements from a functional component in React
We sometimes just want to return a couple of elements next to one another from a React functional co ...