Problem Description
There is a sequence firstly empty. We begin to add number from 1 to N to the sequence, and every time we just add a single number to the sequence at a specific position. Now, we want to know length of the LIS (Longest Increasing Subsequence)
after every time's add.
 

Input
An integer T (T <= 10), indicating there are T test cases.

For every test case, an integer N (1 <= N <= 100000) comes first, then there are N numbers, the k-th number Xk means that we add number k at position Xk (0 <= Xk <= k-1).See hint for more details.
 

Output
For the k-th test case, first output "Case #k:" in a separate line, then followed N lines indicating the answer. Output a blank line after every test case.
 

Sample Input

1
3
0 0 2
 

Sample Output

Case #1:
1
1
2

Hint

In the sample, we add three numbers to the sequence, and form three sequences.
a. 1
b. 2 1
c. 2 1 3

这题看了别人的题解,最后看懂了。题意是从1~n,一次插入位置,然后每插入一个数求出它的最长递增子序列(不连续)。可以用线段树先求出每个数所在的位置,可以从后往前,因为每次最后一个数的位置一定是固定的。然后就是二分法的lis了,这里如果继续用线段树求lis的话会超时的。
这里二分的lis之前一直看不懂,其实因为输入的数是一次增大的,所以每次只要记录这个数的位置,然后二分找到最接近但大于当前数的位置,然后替换掉找到的数。
这题我对二分又有了新的认识,二分模板不是固定的,而是根据题目意思决定最后返回的值是l还是r.
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<algorithm>
using namespace std;
#define maxn 100005
int a[maxn],ans[maxn],dp[maxn];
struct node{
int l,r,n;
}b[4*maxn]; void build(int l,int r,int i)
{
int mid;
b[i].l=l;b[i].r=r;b[i].n=r-l+1;
if(l==r)return;
mid=(l+r)/2;
build(l,mid,i*2);
build(mid+1,r,i*2+1);
} void update(int index,int m,int i)
{
int mid;
if(b[i].l==b[i].r){
b[i].n=0;ans[m]=b[i].l;return;
}
if(b[i*2].n>=index) update(index,m,i*2);
else update(index-b[i*2].n,m,i*2+1);
b[i].n=b[i*2].n+b[i*2+1].n;
} int find(int l,int r,int x)
{
int mid;
while(l<=r){
mid=(l+r)/2;
if(dp[mid]>x){
r=mid-1;
}
else l=mid+1;
}
return r+1; //这里也可以是l,可以草稿纸上画一下
} int main()
{
int n,m,i,j,h,T,k,len; //len表示最长递增子序列
scanf("%d",&T);
for(h=1;h<=T;h++)
{
printf("Case #%d:\n",h);
scanf("%d",&n);
for(i=1;i<=n;i++){scanf("%d",&a[i]);dp[i]=0;}
build(1,n,1);
for(i=n;i>=1;i--){
update(a[i]+1,i,1);
}
len=0;
for(i=1;i<=n;i++){
if(len==0){
dp[++len]=ans[1]; //ans[]表示i所在的位置
printf("%d\n",len);
continue;
}
k=find(1,len,ans[i]);
len=max(len,k); //不管这n个数排列顺序怎样,每一次的最长递增子序列一定是递增的,可以画一下。
dp[k]=ans[i]; //dp[k]表示最长递增序列中的第k个数,用到了单调队列的思想
printf("%d\n",len);
}
printf("\n");
}
return 0;
}

hdu3564 Another LIS的更多相关文章

  1. HDU3564 --- Another LIS (线段树维护最值问题)

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

  2. BZOJ3173:[TJOI2013]最长上升子序列 & HDU3564:Another LIS——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=3173 http://acm.hdu.edu.cn/showproblem.php?pid=3564 ...

  3. Lis日常维护

    1.[问题]护士站打印LIs条码,出来是PDF格式的 [解决]在文件夹Client\NeusoftLis\Xml\Print.xml中把BarcodePrint Name的值改成安装的斑马打印机名(不 ...

  4. uva10635 LIS

    Prince and PrincessInput: Standard Input Output: Standard Output Time Limit: 3 Seconds In an n x n c ...

  5. Codeforces 486E LIS of Sequence 题解

    题目大意: 一个序列,问其中每一个元素是否为所有最长上升子序列中的元素或是几个但不是所有最长上升子序列中的元素或一个最长上升子序列都不是. 思路: 求以每一个元素为开头和结尾的最长上升子序列长度,若两 ...

  6. 出操队形(LIS)

    题目来源:微策略2013年校园招聘面试一面试题 题目描述: 在读高中的时候,每天早上学校都要组织全校的师生进行跑步来锻炼身体,每当出操令吹响时,大家就开始往楼下跑了,然后身高矮的排在队伍的前面,身高较 ...

  7. 洛谷P1108 低价购买[DP | LIS方案数]

    题目描述 “低价购买”这条建议是在奶牛股票市场取得成功的一半规则.要想被认为是伟大的投资者,你必须遵循以下的问题建议:“低价购买:再低价购买”.每次你购买一支股票,你必须用低于你上次购买它的价格购买它 ...

  8. [tem]Longest Increasing Subsequence(LIS)

    Longest Increasing Subsequence(LIS) 一个美丽的名字 非常经典的线性结构dp [朴素]:O(n^2) d(i)=max{0,d(j) :j<i&& ...

  9. 从LIS问题浅谈动态规划

    今天以LIS问题切入动态规划,现在做一些简单的总结. LIS问题: http://www.cnblogs.com/Booble/archive/2010/11/27/1889482.html

随机推荐

  1. 开源:AspNetCore 应用程序热更新升级工具(全网第一份公开的解决方案)

    1:下载.开源.使用教程 下载地址:Github 下载 .其它下载 开源地址:https://github.com/cyq1162/AspNetCoreUpdater 使用教程: 解压AspNetCo ...

  2. SQL中的主键,候选键,外键,主码,外码

    1.码=超键:能够唯一标识一条记录的属性或属性集. 标识性:一个数据表的所有记录都具有不同的超键 非空性:不能为空 有些时候也把码称作"键" 2.候选键=候选码:能够唯一标识一条记 ...

  3. docker cp 拷贝文件 和 进入容器

    进入正在运行的容器 # 进入容器 新开一个终端 # docker exec -it 容器id /bin/bash docker exec -it eaac94ef6926 /bin/bash # 进入 ...

  4. 【Linux】java.io.IOException: error=24, Too many open files解决

    linux系统中执行java程序的时候,如果打开文件超过了限制,就会报错: java.io.IOException: error=24, Too many open files 解决办法: 首先查看j ...

  5. 【Linux】find删除365天以前的文件详细解析

    find . -name "*" -mtime +365 -exec rm -rf {} \; -mtime +365  文件被修改的时间,最后一次发生到现在365天 -atime ...

  6. 【Oracle】密码文件相关

    Oracle数据库的orapwd命令,主要用来建立密码(口令)文件. 一.查看帮助信息 [oracle@oracle11g dbs]$ orapwd Usage: orapwd file=<fn ...

  7. 三种梯度下降算法的区别(BGD, SGD, MBGD)

    前言 我们在训练网络的时候经常会设置 batch_size,这个 batch_size 究竟是做什么用的,一万张图的数据集,应该设置为多大呢,设置为 1.10.100 或者是 10000 究竟有什么区 ...

  8. 被集群节点负载不均所困扰?TKE 重磅推出全链路调度解决方案

    引言 在 K8s 集群运营过程中,常常会被节点 CPU 和内存的高使用率所困扰,既影响了节点上 Pod 的稳定运行,也会增加节点故障的几率.为了应对集群节点高负载的问题,平衡各个节点之间的资源使用率, ...

  9. JWT令牌简介及demo

    一.访问令牌的类型 二.JWT令牌 1.什么是JWT令牌 ​ JWT是JSON Web Token的缩写,即JSON Web令牌,是一种自包含令牌. JWT的使用场景: 一种情况是webapi,类似之 ...

  10. uni-app开发经验分享十四:小程序超过2M限制的方法——分包加载

      起初小程序上线时,微信限制了代码包不能超过1MB,后来功能变大变成了2M了,限制大小是出于对小程序启动速度的考虑,希望用户在使用任何一款小程序时,都能获得一种"秒开"体验.但是 ...