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.删除该位,将其丢在头/尾(开三倍 ...
随机推荐
- GIT学习笔记(2):时光机穿梭与远程仓库
GIT学习笔记(2):时光机穿梭与远程仓库 撤销操作 1.GIT如何跟踪修改 在我们修改了代码内容后,执行了git add和git commit命令来将其交由Git进行版本控制.我们前面举的例子是这样 ...
- cdoj1338郭大侠与英雄学院
地址:http://acm.uestc.edu.cn/#/problem/show/1338 思路: 郭大侠与英雄学院 Time Limit: 6000/2000MS (Java/Others) ...
- JavaScript创建类的三种方式
//第一种 创建类方法. // 用方法模拟 构造函数. function classobj() { this.name = 'xiaoming'; } classobj.text = 'text'; ...
- 【笔记】H5自适应(待)
参考: 1.盒子模型:http://www.cnblogs.com/sunyunh/archive/2012/09/01/2666841.html 2.浮动:http://www.w3school.c ...
- JMeter接口测试和压力测试
JMeter接口测试和压力测试 JMeter可以做接口测试和压力测试.其中接口测试的简单操作包括做http脚本(发get/post请求.加cookie.加header.加权限认证.上传文件).做web ...
- github Git-fork-别人的项目后更新代码的方法
用github还处于菜的阶段,遇到问题简单记录. 举个例子,需要 fork 这个项目 https://github.com/tarobjtu/WebFundamentals.git 点击 for ...
- 20145201 《Java程序设计》第三周学习总结
20145201 <Java程序设计>第三周学习总结 教材学习内容总结 本周学习了课本第四.五章内容,即认识对象和对象封装. 第四章 认识对象 4.1类与对象 定义类 要产生对象必须先定义 ...
- 20145201 《Java程序设计》第一周学习总结(修改)
# 20145201 <Java程序设计>第一周学习总结 ## 教材学习内容总结 万事开头难,终于开始学习了Java.寒假的时候看到老师的要求确实有点慌,但是这周翻开书,从书本知识第一行学 ...
- 《大型网站系统与JAVA中间件实践》读书笔记-消息中间件
消息中间件 1.消息中间件的价值 1.1 透过示例看消息中间件对应用的解耦 1.1.1.通过服务调用让其他系统感知事件发生的方式 假设我们要做一个用户登录系统,其中需要支持的一个功能是,用户登录成功 ...
- Effective C++ 条款02:尽量以const,enum,inline替换 #define
换一种说法就是宁可以编译器替换预处理器 举例 #define ASPECT_RATIO 1.653 记号ASPECT_RATIO也许从未被编译器看见:也许在编译起开始处理源码前它就被预处理器移走了,于 ...