大致题意:

有一个空序列,依次插入1~N到该序列中,每次指定插入的位置,每次插入完成返回当前序列的LIS的长度。

题解:

设dp[i]表示 前缀1~i的最长上升子序列的长度。

因为是按照递增顺序插入的,所以当刚插入完某个数到i位置(此时能保证该数是当前序列的最大值)dp[i] = max{ dp[j] | j<i },答案 ans=max{ dp[i] | i in [1,len] }

因为要支持动态插入,所以要用BST来做,每个节点代表一个位置(即树的中序遍历就是该序列),每个节点维护dp[i]和 dpmax[i] = max{ dp[i] | i in the subtree }

代码:

 #include <cstdio>
#include <iostream>
#define maxn 100010
using namespace std; struct Splay {
int pre[maxn], son[maxn][], siz[maxn], ntot, root;
int dp[maxn], dmax[maxn]; Splay() {
root = ntot = ;
}
void update( int nd ) {
siz[nd] = siz[son[nd][]] + siz[son[nd][]] + ;
dmax[nd] = max( dp[nd], max( dmax[son[nd][]], dmax[son[nd][]] ) );
}
void rotate( int nd, int d ) {
int p = pre[nd];
int s = son[nd][!d];
int ss = son[s][d]; son[nd][!d] = ss;
son[s][d] = nd;
if( !p ) root = s;
else son[p][ nd==son[p][] ] = s; pre[s] = p;
pre[nd] = s;
if( ss ) pre[ss] = nd; update(nd);
update(s);
}
void splay( int nd, int top ) {
while( pre[nd]!=top ) {
int p = pre[nd];
if( pre[p]==top ) {
rotate( p, son[p][]==nd );
} else {
int pp = pre[p];
int pl = p == son[pp][];
int nl = nd == son[p][];
if( pl==nl ) {
rotate( pp, pl );
rotate( p, nl );
} else {
rotate( p, nl );
rotate( pp, pl );
}
}
}
}
int find( int pos ) { // pos in [1,sz]
int nd = root;
while() {
int ls = siz[son[nd][]];
if( pos<=ls ) {
nd = son[nd][];
} else if( pos>=ls+ ) {
nd = son[nd][];
pos -= ls+;
} else {
return nd;
}
}
}
int premax( int pos ) {
int nd = root;
int rt = ;
while() {
int ls = siz[son[nd][]];
if( pos<=ls ) {
nd = son[nd][];
} else if( pos>=ls+ ) {
rt = max( rt, max( dp[nd], dmax[son[nd][]] ) );
nd = son[nd][];
pos -= ls+;
} else {
rt = max( rt, max( dp[nd], dmax[son[nd][]] ) );
break;
}
}
return rt;
}
int newnode( int p, int v ) {
int nd = ++ntot;
pre[nd] = p;
son[nd][] = son[nd][] = ;
siz[nd] = ;
dp[nd] = dmax[nd] = v;
return nd;
}
void insert( int pos ) {
if( !root ) {
root = newnode( , );
return;
}
if( pos== ) {
int nd = root;
while( son[nd][] ) nd=son[nd][];
son[nd][] = newnode( nd, );
update( nd );
splay( nd, );
return;
}
int nd = find( pos );
int nw = newnode( nd,premax(pos)+ );
int s = son[nd][];
son[nd][] = nw;
son[nw][] = s;
pre[nw] = nd;
if( s ) pre[s] = nw;
update( son[nd][] );
update( nd );
splay( nd, );
}
void print( int nd ) {
if( !nd ) return;
print( son[nd][] );
printf( "%d(%d,%d,%d,%d,%d) ", dp[nd], nd, pre[nd], son[nd][], son[nd][], nd==son[pre[nd]][] );
print( son[nd][] );
}
}; Splay T;
int n;
int main() {
//freopen( "input", "r", stdin );
scanf( "%d", &n );
for( int i=,pos; i<=n; i++ ) {
scanf( "%d", &pos );
T.insert( pos );
// T.print(T.root);
// printf( "\n" );
printf( "%d\n", T.dmax[T.root] );
}
}

bzoj3173 Splay 维护前缀中的最大值的更多相关文章

  1. 【BZOJ 3729】3729: Gty的游戏 (Splay维护dfs序+博弈)

    未经博主同意不得转载 3729: Gty的游戏 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 448  Solved: 150 Description ...

  2. BZOJ1014[JSOI2008]火星人prefix(splay维护hash)

    Description 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam,我们将这个字符串的各个字符予以标号:序号: 1 2 3 4 5 6 7 ...

  3. bzoj3786星系探索(splay维护dfs序)

    Description 物理学家小C的研究正遇到某个瓶颈. 他正在研究的是一个星系,这个星系中有n个星球,其中有一个主星球(方便起见我们默认其为1号星球),其余的所有星球均有且仅有一个依赖星球.主星球 ...

  4. 51Nod 1277 字符串中的最大值 ( KMP && DP )

    题意 : 一个字符串的前缀是指包含该字符第一个字母的连续子串,例如:abcd的所有前缀为a, ab, abc, abcd.给出一个字符串S,求其所有前缀中,字符长度与出现次数的乘积的最大值.例如:S ...

  5. 51Nod 1277 字符串中的最大值(KMP,裸题)

    1277 字符串中的最大值 题目来源: Codility 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 一个字符串的前缀是指包含该字符第一个字母的连续子串,例如: ...

  6. 51nod 1277 字符串中的最大值

    题目链接 51nod 1277 字符串中的最大值 题解 对于单串,考虑多串的fail树,发现next数组的关系形成树形结构 建出next树,对于每一个前缀,他出现的次数就是他子树的大小 代码 #inc ...

  7. 51nod 1277字符串中的最大值(拓展kmp)

    题意: 一个字符串的前缀是指包含该字符第一个字母的连续子串,例如:abcd的所有前缀为a, ab, abc, abcd. 给出一个字符串S,求其所有前缀中,字符长度与出现次数的乘积的最大值.   题解 ...

  8. HNOI2004宠物收养所(splay维护二叉搜索树模板题)

    描述 最近,阿Q开了一间宠物收养所.收养所提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物.每个领养者都希望领养到自己满意的宠物,阿Q根据领养者的要求通过他自己发明的一个特殊的公式,得出该领 ...

  9. SPOJ - GSS1-Can you answer these queries I 线段树维护区间连续和最大值

    SPOJ - GSS1:https://vjudge.net/problem/SPOJ-GSS1 参考:http://www.cnblogs.com/shanyr/p/5710152.html?utm ...

随机推荐

  1. CodeForces 1096E: The Top Scorer

    一道经典组合数学+容斥题. 题目传送门:CF1096E. 题意简述: \(p\) 个人,每个人有得分 \(a_i\). 总得分 \(\sum a_i = s\). 第一个人得分 \(a_1 \ge r ...

  2. shell脚本实现监控shell脚本的执行流程及变量的值

    这篇文章主要介绍了shell脚本实现监控shell脚本的执行流程及变量的值本文使用shell完成对执行过程中条件语句中的变量的变化的监控和整个程序的执行流程的观察功能,需要的朋友可以参考下 很多时候, ...

  3. 从此编写 Bash 脚本不再难【转】

    从此编写 Bash 脚本不再难 原创 Linux技术 2017-05-02 14:30 在这篇文章中,我们会介绍如何通过使用 bash-support vim 插件将 Vim 编辑器安装和配置 为一个 ...

  4. 002_curl及postman专题

    一. 步骤 1: 下载cURL工具 使用您的Windows机器从cURL web站点下载最新版本的cURL: (1) 通常情况下,多数的Windows用户可以从官网下载页面http://curl.ha ...

  5. plsql developer配置

    一:今天plsql developer连接 出问题了 ,Oracleclient没正确安装 0.连接vpn 1.环境变量:TNS_ADMIN = D:\worksoftware\oracleClien ...

  6. MySQL学习笔记:Engine存储引擎

    在使用Mysql建表过程中,有时候会遇到一些奇怪的现象.例如,如何插入数据就是查询不到数据,此时可能是建表的存储引擎设置成为engine=blackhole的原因. 1.engine=innodb 提 ...

  7. JavaScript中构造函数

    构造函数:函数的另一种执行方法,执行后创建对象,并创建原型对象. 原型链:对象访问构造函数的指针. Function函数:函数对象. Object函数:所有创建对象的祖辈对象,也是由Function对 ...

  8. Struts 2 - Hello World Example

    As you learnt from the Struts 2 architecture, when you click on a hyperlink or submit an HTML form i ...

  9. 浅谈C、C++及其区别、兼容与不兼容

    一.闲说C C语言之所以命名为C,是因为C语言源自Ken Thompson发明的B语言,而 B语言则源自BCPL语言. 1967年,剑桥大学的Martin Richards对CPL语言进行了简化,于是 ...

  10. Visual Studio 2017各版本安装包离线下载

    关于Visual Studio 2017各版本安装包离线下载.更新和安装的方法以及通过已下载版本减少下载量的办法 微软最近发布了正式版Visual Studio 2017并公开了其下载方式,不过由于V ...