题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3564
题意:给出n个数,串初始为空,Xk表示把k插入到当前串的Xk位置,求每插入一个数后的最长递增子序列的长度
分析:现根据X求出最终每个数的位置 ,求位置数组的LIS即为数的LIS
从后往前遍历X数组,找到第Xk个空着的位置即为K的最终位置,线段树求解
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define N 100005
using namespace std;
int sum[N<<2],a[N],cnt=0,tmp[N];
void pushup(int rt){
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void update(int x,int c,int l,int r,int rt){
if(l==r){
a[x]=r;
sum[rt]=0;
return ;
}
int m=(l+r)>>1;
if(c<=sum[rt<<1])
update(x,c,lson);
else
update(x,c-sum[rt<<1],rson);
pushup(rt);
}
void build(int l,int r,int rt){
if(l==r){
sum[rt]=1;
return ;
}
int m=(l+r)>>1;
build(lson);
build(rson);
pushup(rt);
}
void solve(int n){
vector<int> v;
int Max=0;
for(int i=1;i<=n;i++){
int u=upper_bound(v.begin(),v.end(),a[i])-v.begin();
if(u+1>Max)
Max=u+1;
if(u==v.size())
v.push_back(a[i]);
else
v[u]=a[i];
printf("%d\n",Max);
}
}
int main()
{
int T,n,ics;
scanf("%d",&T);
for(ics=1;ics<=T;ics++){
scanf("%d",&n);
build(1,n,1);
for(int i=1;i<=n;i++){
scanf("%d",&tmp[i]);
}
for(int i=n;i>=1;i--)
update(i,tmp[i]+1,1,n,1);
printf("Case #%d:\n",ics);
solve(n);
printf("\n");
}
return 0;
}