【ZOJ - 3963】Heap Partition (STLset,二叉树的性质,构造,贪心,思维)

题干:

A sequence S = {s1, s2, ..., sn} is called heapable if there exists a binary tree Twith 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 < ihold. 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 (1 ≤ n ≤ 105) — the length of the sequence.

The second line contains n integers a1, a2, ..., 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 Pi1, Pi2, ..., PiCiin 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

题目大意:

用给出的数列a1,a2,a3....an构造二叉树,满足对于下标i和j,有i<j 且ai<=aj满足ai是aj的父节点,问最少需要构造几棵树,并输出每棵树的元素个数和每个元素对应原数组的下标。

解题报告:

从前往后在线处理,用set维护可用节点的权值val和集合编号id和可用子节点数res,每一次贪心找到小于该值的最大的那个节点,插入到其子节点并且维护set中元素(也就是这个元素的根节点的res值),如果找不到该元素,就新开一个集合记录就可以了。注意代码姿势、、、另外因为这题会有重复的val出现,所以需要multiset不能set。

AC代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define F first
#define S second
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
typedef pair<int,int> PII;
const int MAX = 2e5 + 5;
int f[MAX];
struct Node {int val;int res;int id;Node(){}Node(int val,int res,int id):val(val),res(res),id(id){}bool operator<(const Node & b) const {return val < b.val;}
} ;
multiset<Node> ss;
int main()
{int t,n;cin>>t;while(t--) {int tot = 0;ss.clear();scanf("%d",&n);for(int x,i = 1; i<=n; i++) {scanf("%d",&x);auto it = ss.lower_bound(Node(x,0,0));if((int)ss.size()==0 || (it == ss.begin() && (*it).val > x)) {				tot++;f[i] = tot;ss.insert(Node(x,2,f[i]));}else {if(it == ss.end()) --it;auto cur = *it;if(cur.val > x) --it;//找到第一个小于等于该值的。 cur = *it;ss.erase(it);f[i] = cur.id;cur.res--;ss.insert(Node(x,2,f[i]));if(cur.res > 0) ss.insert(cur);}}vector<int> vv[tot+1];for(int i = 1; i<=n; i++) {vv[f[i]].push_back(i);}printf("%d\n",tot);for(int i = 1; i<=tot; i++) {int up = (int)vv[i].size();printf("%d ",up);for(int j = 0; j<up; j++) {printf("%d%c",vv[i][j],j == up-1 ? '\n' :' ');}}}return 0 ;
}

WA的部分:(这样写就WA了,,因为你没有更新set中的值,只是在外面更改了cur)

			else {if(it == ss.end()) --it;auto cur = *it;if(cur.val > x) --it;//找到第一个小于等于该值的。 cur = *it;f[i] = cur.id;cur.res--;ss.insert(Node(x,2,f[i]));if(cur.res == 0) ss.erase(it);}

AC代码2:(set维护下标)

思路就是先从大到小排序,这样就不需要考虑值的大小问题了,这样只需要考虑下标要求的一个小于号,这一点我们可以用set来维护。想法是这样的,相当于我们每次都插入这一个根结点,然后看set里面能否有节点可以当他的孩子节点,注意因为值是由大到小排好序的,所以set里面理论上拿哪一个值都不影响结果的正确性,但是因为这题还需要下标的关系,所以我们还需要二分查找一下合法的下标(因为我们能用的比我们大的值,要求下标也比我大,所以我需要lower或者upper查询(其实这里都一样,因为位置都是unique的),得到我可以用来当孩子结点的下标(一共可以选两个当孩子,选哪个都无所谓,只需要下标满足就可以了),如果实在没有可以当下标的(it == ss.end()),那就只能break掉了,相当于只选择一个当孩子节点。),并将该下标所属的集合改成当前遍历的那个数为根节点的集合。一次类推,最后并查集输出答案就行了。其实还是相当于一个逆向思维,从叶子结点往上构造。但是较AC代码1来说,这个比较难想。

相应的set中从大到小排序,pair从小到大排序,应该也可以做。

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define F first
#define S second
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
typedef pair<int,int> PII;
const int MAX = 2e5 + 5;
set<int> ss;
PII p[MAX];
int f[MAX],tot,n;
int main() {int t;cin>>t;while(t--) {scanf("%d",&n);ss.clear();tot=0;for(int i = 1; i<=n; i++) f[i] = i;for(int x,i = 1; i<=n; i++) {scanf("%d",&x);p[i] = pm(x,i);}sort(p+1,p+n+1,greater<PII>());for(int i = 1; i<=n; i++) {int pos = p[i].S;for(int j = 0; j<2; j++) {auto it = ss.lower_bound(pos);if(it == ss.end()) break;f[*it] = pos;ss.erase(it);}ss.insert(pos);}vector<int> vv[n+1];for(int i = 1; i<=n; i++) {if(f[i] != i) f[i] = f[f[i]];//这里因为每一个f[i]一定是前面的值,并且一定已经是更新好的,所以不需要并查集了,只需要一步压缩就可以了。vv[f[i]].push_back(i);}for(int i = 1; i<=n; i++) {if(vv[i].size()) tot++;}printf("%d\n",tot);for(int i = 1; i<=n; i++) {if(vv[i].empty()) continue;int up = (int)vv[i].size();printf("%d ",up);for(int j = 0; j<up; j++) {printf("%d%c",vv[i][j],j == up-1 ? '\n' :' ');}}}return 0 ;
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/440496.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java poi 3.13_Java 读取Excl文件 (poi-3.13)

最近做项目遇到了读取Excel数据到数据库做数据的初始化。于是找一个。发现(poi-3.13)可以解决问题。可以解析两种格式(xlsx和xls)以下是实现的步骤1.下载poi3.13包&#xff0c;地址(http://poi.apache.org/download.html#POI-3.13)2.学习APi。接下来是还是demo来说明问题吧&…

【CodeChef - CLIQUED 】Bear and Clique Distances(建图,缩点技巧,思维)

题干&#xff1a; 解题报告&#xff1a; 主要就是在于怎么处理那个前K个点&#xff1a;组成一个团。换句话说&#xff0c;缩成一个点。先直接当成每个点多了k条边来处理&#xff0c;T了。想想也是啊&#xff0c;要是K1e5&#xff0c;那就是1e10条边了。。刚开始尝试了半天缩点&…

【HDU - 5649】DZY Loves Sorting(线段树,区间更新区间查询,思维,01缩数变换,线段树分割)

题干&#xff1a; DZY has a sequence a[1..n]a[1..n]. It is a permutation of integers 1∼n1∼n. Now he wants to perform two types of operations: 0lr0lr: Sort a[l..r]a[l..r] in increasing order. 1lr1lr: Sort a[l..r]a[l..r] in decreasing order. After doin…

php错误403_phpstudy访问文件报错403/Forbidden解决办法

使用phpstudy访问WWW目录下的文件时&#xff0c;浏览器提示Forbidden错误&#xff0c;没有访问权限。我在网上搜索了喝多资料以及本人亲自尝试过后&#xff0c;总结了一下两种方法。方法一&#xff1a;打开phpStudy&#xff0c;点击按键“其他选项菜单”>找到phpStudy配置&g…

【CodeForces - 294B】Shaass and Bookshelf(枚举,贪心,思维,组内贪心组间dp)

题干&#xff1a; Shaass has n books. He wants to make a bookshelf for all his books. He wants the bookshelfs dimensions to be as small as possible. The thickness of the i-th book is ti and its pages width is equal to wi. The thickness of each book is eith…

mac php开发集成环境,MAC OS X下php集成开发环境mamp

之前苦于mac上搭建本地服务器之艰辛&#xff0c;找寻好久都没找到一款类似windows上集成的本地服务器环境&#xff0c;诸如phpstudy&#xff0c;xampp,appserv,虽说xampp也有mac版&#xff0c;但不知为何不是Apache启动不了&#xff0c;这里小编为大家分享了MAC OS X 下php集成…

知识点总结vector创建二维数组

vector构造函数通常含有两个参数 原型如下&#xff1a; vector( size_type num, const TYPE &val ); 数量(num)和值(val) - 构造一个初始放入num个值为val的元素的Vector方法1&#xff1a; #include <iostream> #include<vector> #include<algorithm&…

php获取手机目录,php如何获取手机型号

手机App中判断平台&#xff0c;可以根据$_SERVER[HTTP_USER_AGENT]中的内容来判断浏览器类型或手机平台。(推荐学习&#xff1a;PHP编程从入门到精通)iPhone UA&#xff1a;Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_2_1 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, l…

【CodeForces - 920E】Connected Components? (dsu,补图连通块,STLset+map,bfs 或bitset)

题干&#xff1a; You are given an undirected graph consisting of n vertices and edges. Instead of giving you the edges that exist in the graph, we give you m unordered pairs (x, y) such that there is no edge between x and y, and if some pair of vertices…

php获取post全部数据,PHP获取POST数据的几种方法汇总_PHP教程

PHP获取POST数据的几种方法汇总本文给大家汇总介绍了PHP获取POST数据的几种常用方法&#xff0c;这里分享给大家&#xff0c;有需要的小伙伴来参考下吧。一、PHP获取POST数据的几种方法方法1、最常见的方法是&#xff1a;$_POST[‘fieldname’];说明&#xff1a;只能接收Conten…

yiilite.php,缓存 - yii在哪些情况下可以加载yiilite.php?

yii权威指南上说&#xff0c;在开启apc缓存的情况下&#xff0c;可以加载yiilite.php提升性能。我有以下几点疑问&#xff1a;1.开启apc缓存的情况下&#xff0c;引入yiilite.php能提升性能的原因是因为缓存了opcode的关系么&#xff1f;2.使用其他缓存服务缓存opcode的情况下&…

【HDU - 1024 】Max Sum Plus Plus (dp及优化,最大m子段和)

题干&#xff1a; Now I think you have got an AC in Ignatius.Ls "Max Sum" problem. To be a brave ACMer, we always challenge ourselves to more difficult problems. Now you are faced with a more difficult problem. Given a consecutive number sequence…

java 内部类 菜鸟编程,java中的匿名内部类

匿名内部类也就是没有名字的内部类正因为没有名字&#xff0c;所以匿名内部类只能使用一次&#xff0c;它通常用来简化代码编写但使用匿名内部类还有个前提条件&#xff1a;必须继承一个父类或实现一个接口实例1:不使用匿名内部类来实现抽象方法abstract class Person {public …

【牛客 - 551F】CSL 的神奇序列(推公式,猜结论,母函数)

题干&#xff1a; 链接&#xff1a;https://ac.nowcoder.com/acm/contest/551/F 来源&#xff1a;牛客网 题目描述 CSL 有一个神奇的无穷实数序列&#xff0c;他的每一项满足如下关系&#xff1a; 对于任意的正整数 n &#xff0c;有 , 并且 。 CSL 很清楚这样的序列是唯…

java什么时候创建进程,Java创建进程

Java创建进程1 进程的概念 11.1 进程的概念 11.2 进程的特征 11.3 进程与线程区别 12 进程的创建 12.1 JAVA进程的创建 12.1.1 ProcessBuilder 22.1.2 Runtime 32.1.3 Process 42.2 实例 52.2.1 创建子进程 52.2.2 进程阻塞问题 72.2.3 在java中执行java程序 111 进程的概念1.1…

【北航oj】(线段树取模运算)

题干&#xff1a; https://buaacoding.cn/contest-ng/index.html#/334/problems K wjj 的自动售货机 时间限制&#xff1a;1000ms 内存限制&#xff1a;131072kb 通过率&#xff1a;14/26 (53.85%) 正确率&#xff1a;14/119 (11.76%) wjj 最近很看好线下实体销售的行…

matlab 音频编辑器,在Matlab中使用App Designer可以进行实时音频处理吗?

我想用Matlab中的应用程序设计器编写一个简单的音频过滤应用程序。一个人应该能够加载音频文件,按播放和改变参数,如输入增益,截止频率等,而文件正在播放。我只是不知道如何能够实时更改参数并更新相应的变量,以便人们能够听到过滤器是如何更改的。这是我现在写的代码:classdef…

【牛客 - 157E】青蛙(floyd最短路,建图)

题干&#xff1a; 链接&#xff1a;https://ac.nowcoder.com/acm/contest/157/E 来源&#xff1a;牛客网 题目描述 有一只可爱的老青蛙&#xff0c;在路的另一端发现了一个黑的东西&#xff0c;想过去一探究竟。于是便开始踏上了旅途 一直这个小路上有很多的隧道&#xff0…

php移动端url,什么是PC和移动端URL路径规范化

什么叫PC和手机端URL途径规范性在网址百度搜索引擎提升的全过程中&#xff0c;会牵涉到途径方位的难题。网址中的同一个网页页面只相匹配一个网站地址。一个规范化和简易的网站地址有利于检索和捕捉客户的记忆力&#xff0c;回绝好几条途径&#xff0c;偏向同一个网页页面&…

【牛客 - 157D】插排树(dfs,树形dp)

题干&#xff1a; 链接&#xff1a;https://ac.nowcoder.com/acm/contest/157/D 来源&#xff1a;牛客网 一年一度的山东省oi夏令营又开始了&#xff0c;每到这个季节&#xff0c;山东的oier们都会欢聚这里&#xff0c;一起学&#xff08;tu&#xff09;习&#xff08;fe&…