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.删除该位,将其丢在头/尾(开三倍 ...
随机推荐
- html-2, a img ul li ol dl dt dd 标签与列表标签的简单使用
<!-- a: a{ /*清除a标签的下划线*/ text-decoration: none; } (1)超链接 href 超链接的地址 target: _self 默认 在当前中打开链接地 ...
- nodejs多核处理
前言大家都知道nodejs是一个单进程单线程的服务器引擎,不管有多么的强大硬件,只能利用到单个CPU进行计算.所以,有人开发了第三方的cluster,让node可以利用多核CPU实现并行. 随着nod ...
- HDU4639
/*计算里面有多少个相邻的he,1个he就是1种意思,两个就是,两种,所以这是 一个斐波拉期数列,间隔的hehe互不影响所以是互斥事件,直接相乘就可以*/ #include<stdio.h> ...
- QT中没有byte
QT里没有没有byte数据类型的 自己定义:#define byte unsigned char
- 华为S5700系列交换机配置通过流策略实现VLAN间三层隔离
组网图形 图1 配置通过流策略实现VLAN间三层隔离组网图 组网需求 如图一所示,为了通信的安全性,某公司将访客.员工.服务器分别划分到VLAN10.VLAN20.VLAN30中.公司希望: 员工.服 ...
- Linux下MySQL 5.6.24的编译安装与部署
MySQL 5.6正式版发布了,相对于5.5版本作出了不少改进,其源码安装配置方式也有所变化,本文根据实际操作,不断尝试,精确还原了安装的具体步骤. 在Linux下安装MySQL前,先确认卸载系统自带 ...
- Java Lambda表达
Java 8 lambda表达式示例 我个人对Java 8发布非常激动,尤其是lambda表达式和流API.越来越多的了解它们,我能写出更干净的代码.虽然一开始并不是这样.第一次看到用lambda表达 ...
- idea技巧
写在前面 以前一直用的elipce,如今入坑IntelliJ IDEA,没想到啊.深深的爱上了它,强大到无所不能: "工欲善其事必先利其器",IntelliJ IDEA作为一个非常 ...
- Luogu-3648 [APIO2014]序列分割
Luogu-3648 [APIO2014]序列分割 题目链接 题解: 首先要发现一个重要的性质:分割的顺序是不会影响答案的 证明: 首先对于没有交的两段区间,显然先后顺序改变不会有影响 而对于在同一段 ...
- 洛谷P4311 士兵占领
题目描述 有一个M * N的棋盘,有的格子是障碍.现在你要选择一些格子来放置一些士兵,一个格子里最多可以放置一个士兵,障碍格里不能放置士兵.我们称这些士兵占领了整个棋盘当满足第i行至少放置了Li个士兵 ...