题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=3564

题意:给你N个数的位置。数i的位置为第i个数,比如 0 0 2,表示1插在第0个位置,此时数列为{1},2插在第0个位置,此时数列为{2,1},3插在第2个位置,此时数列为{2,1,3},每插一个位置,要求输出当前最大的LIS。

题解:很巧妙的求法,首先要先用线段树插空法将原数列的位置还原出来,然后从1到n,数肯定是递增的,如果位置也是递增的,那么就肯定是最长递增数列,然后用nlogn的LIS求出答案,因为插入的顺序是按1-n的顺序插入的,我们还原位置后,直接对位置进行求LIS,即为当前数的LIS,关于LIS的求法传输门:http://blog.csdn.net/bin_gege/article/details/51789261

线段树插空法:因为最后插入的数的位置肯定是固定的,所以我们记录数后,倒着插,每插入一个数,要保证这个数的位置k前有k-1个空位,这样后面的数才能插进去

 #include<cstdio>
#include<algorithm>
#define F(i,a,b) for(int i=a;i<=b;i++)
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
using namespace std;
const int N=1e5+;
int t,n,x,ic=,nd[N<<],d[N],dp[N],a[N],len;
void build(int l=,int r=n,int rt=){
nd[rt]=r-l+;//保存当前区间的空位数
if(l==r)return;
int m=(l+r)>>;
build(ls),build(rs);
}
void update(int x,int c,int l=,int r=n,int rt=){
if(l==r){d[c]=l,nd[rt]=;return;}
int m=(l+r)>>;nd[rt]--;
if(x<=nd[rt<<])update(x,c,ls);//如果左儿子的空位大于等于位置
else update(x-nd[rt<<],c,rs);//如果小于,就插入又儿子中,在右儿子中插入的位置应该减掉左儿子的空位数
}
int main(){
scanf("%d",&t);
while(t--){
scanf("%d",&n),build(),len=;
F(i,,n)scanf("%d",a+i),dp[i]=;
for(int i=n;i>;i--)update(a[i]+,i);
printf("Case #%d:\n",ic++);
F(i,,n){
if(i==)dp[]=d[],puts("");
else{
int k=lower_bound(dp+,dp+len+,d[i])-dp;
if(len<k)dp[k]=d[i],len=k;
else if(d[i]<dp[k])dp[k]=d[i];
printf("%d\n",len);
}
}
puts("");
}
return ;
}

hdu_3564_Another LIS(线段树+LIS)的更多相关文章

  1. Hdu 3564 Another LIS 线段树+LIS

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission( ...

  2. HDU - 3564 Another LIS(LIS+线段树)

    http://acm.hdu.edu.cn/showproblem.php?pid=3564 题意 给出1~n的插入顺序,要求每次插入之后的LIS 分析 首先用线段树还原出最终序列.因为插入的顺序是按 ...

  3. POJ 3903 Stock Exchange(LIS || 线段树)题解

    题意:求最大上升子序列 思路:才发现自己不会LIS,用线段树写的,也没说数据范围就写了个离散化,每次查找以1~a[i]-1结尾的最大序列答案,然后更新,这样遍历一遍就行了.最近代码总是写残啊... 刚 ...

  4. Codeforces 486E LIS of Sequence(线段树+LIS)

    题目链接:Codeforces 486E LIS of Sequence 题目大意:给定一个数组.如今要确定每一个位置上的数属于哪一种类型. 解题思路:先求出每一个位置选的情况下的最长LIS,由于開始 ...

  5. 2015合肥网络赛 HDU 5489 Removed Interval LIS+线段树(树状数组)

    HDU 5489 Removed Interval 题意: 求序列中切掉连续的L长度后的最长上升序列 思路: 从前到后求一遍LIS,从后往前求一遍LDS,然后枚举切开的位置i,用线段树维护区间最大值, ...

  6. D. Babaei and Birthday Cake---cf629D(LIS线段树优化)

    题目链接:http://codeforces.com/problemset/problem/629/D 题意就是现有n个蛋糕,蛋糕的形状是圆柱体,每个蛋糕的体积就是圆柱体的体积,每个蛋糕的编号是1-- ...

  7. HDU 4521 间隔》=1的LIS 线段树+dp

    九野的博客,转载请注明出处:http://blog.csdn.net/acmmmm/article/details/11991119 题意: n个数 d个距离 下面n个数的序列,求序列中的最长单调递增 ...

  8. BZOJ2957: 楼房重建(线段树&LIS)

    2957: 楼房重建 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 3727  Solved: 1793[Submit][Status][Discus ...

  9. SGU 521 North-East ( 二维LIS 线段树优化 )

    521. "North-East" Time limit per test: 0.5 second(s)Memory limit: 262144 kilobytes input: ...

随机推荐

  1. COM与.NET程序集导出和部署COM组件

    为了分布式和多客户端调用我们还需要将写好的COM组件发布到一台服务器上.这里我们将组件部署到操作系统的COM+应用程序中去.如果没此需要就可以导出后,在C++环境中调用COM了. 第一步:导出COM组 ...

  2. ClassLoader类加载解惑

    1.通过类加载器获取路径: String path = Thread.currentThread().getContextClassLoader().getResource("." ...

  3. hibernate的批量更新、批量删除

    hibernate的批处理API:session.createQuery(hql).executeUpdate(),如果有参数则在执行之前设置参数. 批量更新示例: @Test public void ...

  4. 利用socket模块检查端口存活并邮件警报

    可以用来监控一些端口. import socket def check_server(addr, port): s = socket.socket() try: s.connect((addr, po ...

  5. ios 基础数据类型

    1:NSString http://blog.csdn.net/likendsl/article/details/7417878 http://xys289187120.blog.51cto.com/ ...

  6. HDU 2732 Leapin' Lizards

    网络最大流+拆点.输出有坑!!! #include<cstdio> #include<cstring> #include<string> #include<c ...

  7. 字符串匹配算法之KMP

    字符串匹配是计算机的基本任务之一. 举例来说,有一个字符串"BBC ABCDAB ABCDABCDABDE",我想知道,里面是否包含另一个字符串"ABCDABD" ...

  8. Linux Shell : Test命令参数解析

    格式: test conditions test -n string : string 不为空 test -z string : string 为空 test int1 -eq int2  : int ...

  9. apt-get 依赖修复

    apt-get cleanapt-get update apt-get -f install dpkg --configure -a

  10. LD_LIBRARY_PATH vs LIBRARY_PATH

    LIBRARY_PATH is used by gcc before compilation to search for directories containing libraries that n ...