zoj 3963 Heap Partition(贪心)

Heap Partition


Time Limit: 2 Seconds      Memory Limit: 65536 KB      Special Judge


A sequence S = {s1s2, ..., 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 sjsj ≤ 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 a1a2, ..., 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 (1 ≤ n ≤ 105) — the length of the sequence.

The second line contains n integers a1a2, ..., an (1 ≤ ai ≤ n).

It is guaranteed that the sum of all n does not exceed 2 × 106.

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 Pi1Pi2, ..., 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

4
4
1 2 3 4
4
2 4 3 1
4
1 1 1 1
5
3 2 1 4 1

Sample Output

1
4 1 2 3 4
2
3 1 2 3
1 4
1
4 1 2 3 4
3
2 1 4
1 2
2 3 5

Hint

d.构造尽可能少的最小堆,

比如样例2中,最少可构造2个,分别是2 4 3和1

输出的是数字在原序列中的位置

s.前面的数字从小到大排序,贪心选择尽可能大的构造

如果找不到比当前数字小的,则当前数字作为根,添加一个堆

样例较大,用set来写,二分查找比较快

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3
 4 const int MAXN = 1e5 + 5;
 5
 6 struct Node {
 7     int id;
 8     int val;
 9 } a[MAXN];
10
11 int fa[MAXN];
12 int childNum[MAXN];//
13
14 struct NodeCmp {
15     bool operator()(const Node &a, const Node &b)
16     {
17         if (a.val != b.val) return a.val < b.val;
18         return a.id < b.id;
19     }
20 };
21
22 set<Node, NodeCmp> st;//按val排序
23 vector<int> vt[MAXN];//保存儿子节点
24 vector<int> vt2;//保存父节点
25
26 int setFind(int d)
27 {
28     if (fa[d] < 0) {
29         return d;
30     }
31     return fa[d] = setFind(fa[d]);
32 }
33
34 void setJoin(int x, int y)
35 {
36     x = setFind(x);
37     y = setFind(y);
38     if (x != y) fa[x] = y;
39 }
40
41 int main()
42 {
43     int T;
44     int n;
45     int i, j;
46     Node tmp;
47     set<Node>::iterator it;
48     int tmp2;//
49
50     scanf("%d", &T);
51
52     while (T--) {
53         //这样初始化超时
54         //memset(fa, -1, sizeof(fa));
55         //memset(childNum, 0, sizeof(childNum));
56         scanf("%d", &n);
57         memset(fa, -1, sizeof(int) * (n + 1));
58         memset(childNum, 0, sizeof(int) * (n + 1));
59         st.clear();
60         vt2.clear();
61         for (i = 0; i < n; ++i) {
62             scanf("%d", &a[i].val);
63             a[i].id = i + 1;
64             it = st.upper_bound(a[i]);
65             if (it == st.begin()) {//
66                 st.insert(a[i]);
67                 vt2.push_back(a[i].id);
68             } else {
69                 tmp = *(--it);
70                 setJoin(a[i].id, tmp.id);
71                 ++childNum[tmp.id];
72                 if (childNum[tmp.id] >= 2) {
73                     st.erase(tmp);
74                 }
75
76                 vt[setFind(tmp.id)].push_back(a[i].id);//加到根节点孩子列表
77                 st.insert(a[i]);
78             }
79         }
80
81         printf("%d\n", vt2.size());
82         for (i = 0; i < vt2.size(); ++i) {
83             tmp2 = vt2[i];//根节点
84             printf("%d", vt[tmp2].size());
85             printf(" %d", tmp2);//根节点
86             for (j = 0; j < vt[tmp2].size(); ++j) {//孩子节点
87                 printf(" %d", vt[tmp2][j]);
88             }
89             vt[tmp2].clear();//在这里清空比较好
90         }
91     }
92
93     return 0;
94 }
时间: 2024-10-27 06:08:30

zoj 3963 Heap Partition(贪心)的相关文章

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

题意:给你n个数字s1~sn,要你把它们组成一棵棵二叉树,对这棵二叉树来说,所有节点来自S,并且父节点si<=子节点sj,并且i<j,问你树最少几棵二叉数.树 思路:贪心.我们往multiset加还能加子节点的节点,二分查找一个个大于等于当前插入节点的节点,然后插入,若找不到则重新建一棵树. 没想到set自带lower_bound(),第一次迭代器遍历TLE就想着手动写二分...然后发现自带二分... 代码: #include<iostream> #include<stdio

zoj 3963 heap partion

https://vjudge.net/problem/ZOJ-3963 题意: 给出一个数列,可以用这个数列构造一种二叉树,这个二叉树满足数的下标 i <= j,并且 si <= sj,si是sj的父亲,问给出的数列可以构造多少棵这样的二叉树. 思路: 这题赛上没有写出来,看了题解之后给补的. 首先,通过这题学到了,memset初始化数组有时是会造成超时的.set的upper_bound(x)这个函数,它返回set中大于x的第一个元素的位置(注意是大于,不是大于等于). 于是,这题就是贪心加s

ZOJ 3607 Lazier Salesgirl (贪心)

Lazier Salesgirl Time Limit: 2 Seconds      Memory Limit: 65536 KB Kochiya Sanae is a lazy girl who makes and sells bread. She is an expert at bread making and selling. She can sell the i-th customer a piece of bread for price pi. But she is so lazy

ZOJ 3946 Highway Project 贪心+最短路

题目链接: http://www.icpc.moe/onlinejudge/showProblem.do?problemCode=3946 题解: 用dijkstra跑单元最短路径,如果对于顶点v,存在一系列边(ui,v)使得dis[v]最小(dis[v]表示0到v的距离).这些边能且只能选一条,那么我们自然应该选cost最小的那个边了. 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #inc

zoj 3778 Talented Chef 贪心

zoj 3778 Talented Chef 题意: 有n个饼,给出完成每个饼所需要的时间t1,t2,...,tn,现在有m个锅(也就是说可以同时煎m个饼),问完成所有饼至少需要多少时间. 限制: 1 <= n,m,ti <= 40000 思路: 贪心 ans=max(ceil(sigma(1~n,ti)/m),max(ti)) /*zoj 3778 Talented Chef 题意: 有n个饼,给出完成每个饼所需要的时间t1,t2,...,tn,现在有m个锅(也就是说可以同时煎m个饼),问完

hdu-5646 DZY Loves Partition(贪心)

题目链接: DZY Loves Partition Time Limit: 4000/2000 MS (Java/Others)     Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 323    Accepted Submission(s): 127 Problem Description DZY loves partitioning numbers. He wants to know whether it is

ZOJ 2702 Unrhymable Rhymes 贪心

贪心,能凑成一组就算一组 Unrhymable Rhymes Time Limit: 10 Seconds      Memory Limit: 32768 KB      Special Judge An amateur poet Willy is going to write his first abstract poem. Since abstract art does not give much care to the meaning of the poem, Willy is plan

ZOJ 3689 Digging(贪心+dp)

Digging Time Limit: 2 Seconds      Memory Limit: 65536 KB When it comes to the Maya Civilization, we can quickly remind of a term called the end of the world. It's not difficult to understand why we choose to believe the prophecy (or we just assume i

ZOJ 1025. Wooden Sticks 贪心 结构体排序

Wooden Sticks Time Limit: 2 Seconds      Memory Limit: 65536 KB There is a pile of n wooden sticks. The length and weight of each stick are known in advance. The sticks are to be processed by a woodworking machine in one by one fashion. It needs some