zoj-3963 Heap Partition(贪心+二分+树状数组)
题目链接:
Time Limit: 2 Seconds Memory Limit: 65536 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 (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, ..., 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 题意:给出一个序列,然后要求分成最少多少个子序列,使得每个子序列都满足上面的要求 思路:贪心,对于a[i],贪心的话就是要在a[1]~a[i-1]中找到一个a[j]做父亲(且a[j]不能超过两个孩子),a[j]<=a[i]&&a[j]>=a[k](1<=任意k<=i-1,k!=j)
可以离散化,然后二分+树状数组找,线段树会T;
AC代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
template<class T> void read(T&num) {
char CH; bool F=false;
for(CH=getchar();CH<'0'||CH>'9';F= CH=='-',CH=getchar());
for(num=0;CH>='0'&&CH<='9';num=num*10+CH-'0',CH=getchar());
F && (num=-num);
}
int stk[70], tp;
template<class T> inline void print(T p) {
if(!p) { puts("0"); return; }
while(p) stk[++ tp] = p%10, p/=10;
while(tp) putchar(stk[tp--] + '0');
putchar('\n');
} int n,a[maxn],vis[maxn],p[maxn],b[maxn],sum[maxn];
vector<int>ve[maxn];
struct node
{
int a,id;
}po[maxn];
int cmp(node x,node y)
{
if(x.a==y.a)return x.id<y.id;
return x.a<y.a;
}
inline int lowbit(int x){return x&(-x);}
inline int query(int x)
{
int s=0;
while(x)
{
s+=sum[x];
x-=lowbit(x);
}
return s;
}
inline void update(int x,int num)
{
while(x<=n)
{
sum[x]+=num;
x+=lowbit(x);
}
return ;
} inline int solve(int x)
{
int l=1,r=b[x]-1;
while(l<=r)
{
int mid=(l+r)>>1;
if(query(b[x]-1)-query(mid-1)>0)l=mid+1;
else r=mid-1;
}
if(l-1<=0)return -1;
return p[l-1];
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i=1;i<=n;i++)read(po[i].a),po[i].id=i,ve[i].clear(),sum[i]=0;
sort(po+1,po+n+1,cmp);
for(int i=1;i<=n;i++)b[po[i].id]=i,p[i]=po[i].id;
int ans=0;
for(int i=1;i<=n;i++)
{
int pos=solve(i);
if(pos==-1)ans++,vis[i]=ans,ve[ans].push_back(i);
else vis[i]=vis[pos],ve[vis[i]].push_back(i),update(b[pos],-1);
update(b[i],2);
}
printf("%d\n",ans);
for(int i=1;i<=ans;i++)
{
int len=ve[i].size();
printf("%d",len);
for(int j=0;j<len;j++)printf(" %d",ve[i][j]);puts("");
}
}
return 0;
}
zoj-3963 Heap Partition(贪心+二分+树状数组)的更多相关文章
- zoj 3963 Heap Partition(并查集,贪心,二分)
Heap Partition Time Limit: 2 Seconds Memory Limit: 65536 KB Special Judge A sequence S = { ...
- 【BZOJ-2527】Meteors 整体二分 + 树状数组
2527: [Poi2011]Meteors Time Limit: 60 Sec Memory Limit: 128 MBSubmit: 831 Solved: 306[Submit][Stat ...
- 【BZOJ3110】【整体二分+树状数组区间修改/线段树】K大数查询
Description 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c 如果是2 a b c形式,表示询问从第a个位置到第b个位 ...
- BZOJ_3110_[Zjoi2013]K大数查询_整体二分+树状数组
BZOJ_3110_[Zjoi2013]K大数查询_整体二分+树状数组 Description 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位 ...
- bzoj千题计划316:bzoj3173: [Tjoi2013]最长上升子序列(二分+树状数组)
https://www.lydsy.com/JudgeOnline/problem.php?id=3173 插入的数是以递增的顺序插入的 这说明如果倒过来考虑,那么从最后一个插入的开始删除,不会对以某 ...
- 【bzoj3110】[Zjoi2013]K大数查询 整体二分+树状数组区间修改
题目描述 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c.如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数 ...
- 【bzoj4009】[HNOI2015]接水果 DFS序+树上倍增+整体二分+树状数组
题目描述 给出一棵n个点的树,给定m条路径,每条路径有一个权值.q次询问求一个路径包含的所有给定路径中权值第k小的. 输入 第一行三个数 n和P 和Q,表示树的大小和盘子的个数和水果的个数. 接下来n ...
- 【bzoj2527】[Poi2011]Meteors 整体二分+树状数组
题目描述 有N个成员国.现在它发现了一颗新的星球,这颗星球的轨道被分为M份(第M份和第1份相邻),第i份上有第Ai个国家的太空站. 这个星球经常会下陨石雨.BIU已经预测了接下来K场陨石雨的情况.BI ...
- [ZJOI2006]书架(二分+树状数组)
这题90%以上的人做法为裸的平衡树,实际上根本没必要还常数大,最好的方法是二分+树状数组.具体做法是,开3倍内存,初始把中间n位赋值为1.对于每个操作:1&2.删除该位,将其丢在头/尾(开三倍 ...
随机推荐
- Delphi 正则表达式之TPerlRegEx 类的属性与方法(6): EscapeRegExChars 函数
Delphi 正则表达式之TPerlRegEx 类的属性与方法(6): EscapeRegExChars 函数 // EscapeRegExChars 函数可以自动为特殊字符加转义符号 \ var ...
- 第一课Linux系统安装知识(2)
接着上节课单击Finish按钮之后,虚拟机将会启动进入安装界面. 根据提示按回车选择图形界面安装. 这里选择Skip跳过媒介检查. 选择安装语言为简体中文,键盘鼠标默认项即可. 这里安装类型选择是定制 ...
- Eclipse 中安装Browse Deployment Location插件
Browse Deployment Location 功能的插件名称为: Pivotal tc Server Integration for Eclipse 可在Eclippse的Eclipse M ...
- 分支语句(switch case)
/switch case 的应用 Console.WriteLine("1.汉堡包"); Console.WriteLine("2.薯条"); Console. ...
- Java并发之CyclicBarria的使用(二)
Java并发之CyclicBarria的使用(二) 一.简介 之前借助于其他大神写过一篇关于CyclicBarria用法的博文,但是内心总是感觉丝丝的愧疚,因为笔者喜欢原创,而不喜欢去转载一些其他的文 ...
- Mybatis中trim的使用
trim标记是一个格式化的标记,可以完成set或者是where标记的功能,如下代码: 1. select * from user <trim prefix="WHERE" p ...
- WPF MVVM模式下ComboBox级联效果 选择第一项
MVVM模式下做的省市区的级联效果.通过改变ComboBox执行命令改变市,区. 解决主要问题就是默认选中第一项 1.首先要定义一个属性,继承自INotifyPropertyChanged接口.我这里 ...
- 【leetcode刷题笔记】Majority Element
Given an array of size n, find the majority element. The majority element is the element that appear ...
- Openstack之Nova创建虚机流程分析
前言 Openstack作为一个虚拟机管理平台,核心功能自然是虚拟机的生命周期的管理,而负责虚机管理的模块就是Nova. 本文就是openstack中Nova模块的分析,所以本文重点是以 ...
- c++的格式控制
1: 每个iostream对象维持一个控制IO格式化细节的格式状态.标准库定义了一组操纵符来修改对象的格式状态.所谓操纵符是可用作输入或输出操作符的函数或对象.iostream和iomanip头文件中 ...