Written with StackEdit.

Description

给定一个序列,初始为空。现在我们将\(1\)到\(N\)的数字插入到序列中,每次将一个数字插入到一个特定的位置。每插入一个数字,我们都想知道此时最长上升子序列长度是多少?

Input

第一行一个整数\(N\),表示我们要将\(1\)到\(N\)插入序列中,接下是\(N\)个数字,第\(k\)个数字\(X_k\),表示我们将\(k\)插入到位置\(X_k(0\leq X_k\leq k-1,1\leq k\leq N)\),

Output

\(N\)行,第\(i\)行表示\(i\)插入\(X_i\)位置后序列的最长上升子序列的长度是多少。

Sample Input

3

0 0 2

Sample Output

1

1

2

HINT

\(100\%\)的数据 \(n\leq100000\).

Solution

  • 如果我们已经得到了最后的序列,我们可以用\(O(nlogn)\)的算法计算出\(LIS\),同时维护\(ans[i]\),表示以\(i\)作为结尾的上升子序列的最大长度.
  • 再令\(g[i]\)表示最终要输出的答案,即插入\(i\)后的\(LIS\)长度.
  • 因为整个序列是从小到大插入的,所以\(g[i]=max_{j=1}^{i}ans[j].\)
  • 使用前缀和优化一下即可.
  • 维护元素的插入可以写一颗平衡树.
#include<bits/stdc++.h>
using namespace std;
typedef long long LoveLive;
inline int read()
{
int out=0,fh=1;
char jp=getchar();
while ((jp>'9'||jp<'0')&&jp!='-')
jp=getchar();
if (jp=='-')
{
fh=-1;
jp=getchar();
}
while (jp>='0'&&jp<='9')
{
out=out*10+jp-'0';
jp=getchar();
}
return out*fh;
}
const int MAXN=1e5+10;
int a[MAXN],qlen=0;
int n;
struct FhqTreap
{
int x,y;
struct node
{
int lson,rson,siz,weight,key;
} treap[MAXN];
int idx,root;
FhqTreap()
{
x=0,y=0;
idx=0;
root=0;
treap[0].key=0;
treap[0].lson=treap[0].rson=0;
treap[0].weight=0;
treap[0].siz=0;
}
#define rt treap[o]
#define ls treap[treap[o].lson]
#define rs treap[treap[o].rson]
inline int newnode(int key)
{
int o=++idx;
rt.lson=rt.rson=0;
rt.siz=1;
rt.weight=rand();
rt.key=key;
return o;
}
inline void pushup(int o)
{
rt.siz=ls.siz+rs.siz+1;
}
int merge(int x,int y)
{
if(!x || !y)
return x+y;
if(treap[x].weight<treap[y].weight)
{
treap[x].rson=merge(treap[x].rson,y);
pushup(x);
return x;
}
else
{
treap[y].lson=merge(x,treap[y].lson);
pushup(y);
return y;
}
}
void split(int &x,int &y,int k,int o)
{
if(!o)
x=y=0;
else
{
if(k<=ls.siz)
{
y=o;
split(x,rt.lson,k,rt.lson);
}
else
{
x=o;
split(rt.rson,y,k-ls.siz-1,rt.rson);
}
pushup(o);
}
}
void ins(int key,int pos)
{
split(x,y,pos,root);
y=merge(newnode(key),y);
root=merge(x,y);
}
void dfs(int o)
{
if(!o)
return;
dfs(rt.lson);
a[++qlen]=rt.key;
dfs(rt.rson);
}
void getseq()
{
dfs(root);
}
}T;
#define inf 0x7fffffff
int f[MAXN],ans[MAXN];
int main()
{
srand(19260817);
n=read();
for(int i=1;i<=n;++i)
{
int pos=read();
T.ins(i,pos);
}
T.getseq();
memset(f,0x7f,sizeof f);
f[0]=-inf;
for(int i=1;i<=n;++i)
{
int t=upper_bound(f,f+n+1,a[i])-f;
f[t]=a[i];
ans[a[i]]=t;
}
for(int i=1;i<=n;++i)
printf("%d\n",ans[i]=max(ans[i-1],ans[i]));
puts("");
return 0;
}

bzoj 3173 最长上升子序列的更多相关文章

  1. BZOJ 3173 最长上升子序列(树状数组+二分+线段树)

    给定一个序列,初始为空.现在我们将1到N的数字插入到序列中,每次将一个数字插入到一个特定的位置.每插入一个数字,我们都想知道此时最长上升子序列长度是多少? 由于序列是顺序插入的,所以当前插入的数字对之 ...

  2. BZOJ.3591.最长上升子序列(状压DP)

    BZOJ 题意:给出\(1\sim n\)的一个排列的一个最长上升子序列,求原排列可能的种类数. \(n\leq 15\). \(n\)很小,参照HDU 4352这道题,我们直接把求\(LIS\)时的 ...

  3. BZOJ 2423 最长公共子序列

    Description 字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列.令给定的字符序列X=“x0,x1,…,xm-1”,序列Y=“y0, ...

  4. 【刷题】BZOJ 3591 最长上升子序列

    Description 给出1~n的一个排列的一个最长上升子序列,求原排列可能的种类数. Input 第一行一个整数n. 第二行一个整数k,表示最长上升子序列的长度. 第三行k个整数,表示这个最长上升 ...

  5. BZOJ 5427: 最长上升子序列

    $f[i] 表示长度为i的最长上升子序列的最后一位的最小值是多少$ 对于普通的$LIS我们可以二分确定位置去更新$ 再来考虑对于这个,如果有某一位没有确定的话 那么这一位是可以随便取的,也就是说,所有 ...

  6. BZOJ 5161: 最长上升子序列 状压dp+查分

    好神啊 ~ 打表程序: #include <cstdio> #include <cstring> #include <algorithm> #define N 14 ...

  7. [BZOJ 3173] [TJOI 2013] 最长上升子序列(fhq treap)

    [BZOJ 3173] [TJOI 2013] 最长上升子序列(fhq treap) 题面 给定一个序列,初始为空.现在我们将1到N的数字插入到序列中,每次将一个数字插入到一个特定的位置.每插入一个数 ...

  8. BZOJ 3173: [Tjoi2013]最长上升子序列

    3173: [Tjoi2013]最长上升子序列 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1524  Solved: 797[Submit][St ...

  9. BZOJ 3173 [Tjoi2013] 最长上升子序列 解题报告

    这个题感觉比较简单,但却比较容易想残.. 我不会用树状数组求这个原排列,于是我只好用线段树...毕竟 Gromah 果弱马. 我们可以直接依次求出原排列的元素,每次找到最小并且最靠右的那个元素,假设这 ...

随机推荐

  1. Hadoop2.7.x中所有的DataNode都启动不了解决办法

    参考:Hadoop集群所有的DataNode都启动不了解决办法说明现象:我自己出现这个问题的原因是:自己在namenode格式化之后创建了一些文件,然后重新执行了namenode格式化导致的. 现象就 ...

  2. canvas笔记1

    w3c定义: <canvas> 标签定义图形,比如图表和其他图像. <canvas> 标签只是图形容器,您必须使用脚本来绘制图形. canvas 对象 属性: width he ...

  3. 一般处理程序中 C#中对象转化为Json对象

    namespace: Newtonsoft.Json; context.Response.ContentType = "application/text"; 注:这里为什么不是 J ...

  4. J2EE--Struts2基础开发笔记

    内容中包含 base64string 图片造成字符过多,拒绝显示

  5. react native 中的ReadableMap和WritableMap的使用

    react native跟安卓原生交互的数据类型中,有两个比较陌生的类型,ReadableMap和WritableMap. ReadableMap和WritableMap,顾名思义,反正是map. W ...

  6. Spring_IOC&DI概述

  7. Swift学习笔记 - 位移枚举的按位或运算

    在OC里面我们经常遇到一些枚举值可以多选的,需要用或运算来把这些枚举值链接起来,这样的我们称为位移枚举,但是在swift里面却不能这么做,下面来讲解一下如何在swift里面使用 OC的位移枚举的区分 ...

  8. Effective C++ 条款11:在operator=中处理"自我赋值"

    "自我赋值"发生在对象被赋值给自己时: class Widget { ... }; Widget w; ... w = w; // 赋值给自己 a[i] = a[j]; // 潜在 ...

  9. 22个HTML5的初级技巧

    Web技术的发展速度太快了,如果你不与时俱进,就会被淘汰.因此,为了应对即将到来的HTML5,本文总结了22个HTML5的初级技巧,希望能对你进一步学习好HTML5会有所帮助. 1. 新的Doctyp ...

  10. Redis分区探究

    Redis比较好的分区算法是采用Hash分区算法 也就是我们可以将所有的server例如:user1,user2,user3.通过hash函数将key转化为一个数字然后求余找到需要存储的server. ...