大致题意:

有一个空序列,依次插入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. Find Minimum in Rotated Sorted Array I & II

    Find Minimum in Rotated Sorted Array I Suppose a sorted array is rotated at some pivot unknown to yo ...

  2. go 匿名函数和闭包

    匿名函数 1. 函数也是一种类型,因此可以定义作为一个函数类型的变量 package main import "fmt" // 函数作为参数 func add(a, b int) ...

  3. 【Git】Git与GitHub 入门【转】

    转自:http://www.cnblogs.com/lcw/p/3394545.html GitHub GitHub是一个基于git的代码托管平台,付费用户可以建私人仓库,我们一般的免费用户只能使用公 ...

  4. linux音频alsa-uda134x驱动分析之二(时钟)

    Audio Clocking音频时钟============== This text describes the audio clocking terms in ASoC and digital au ...

  5. window.print打印方法实现

    vue中使用window.print打印效果 项目要求 打印每页有10行表格,如果接口数据没有十个显示10行 效果图 第一页 第二页 子组件 <template> <div> ...

  6. python网络编程--线程GIL(全局解释器锁)

    一:什么是GIL 在CPython,全局解释器锁,或GIL,是一个互斥体防止多个本地线程执行同时修改同一个代码.这把锁是必要的主要是因为当前的内存管理不是线程安全的.(然而,由于GIL存在,其他特性已 ...

  7. js中的盒子模型

    说到盒子模型,你第一时间会想到css盒子模型,css中的盒子模型包括(内容区+内边距+边框).那在js中怎么去获取这些属性值呢?下面一起来学习js中的盒子模型. css样式 body { margin ...

  8. Oracle 函数 “申请通过后,将该表中循环遍历到的所有内容插到另一个表中”

    create or replace function mcode_apply_insert_material(p_mca_no VARCHAR2, p_action VARCHAR2, p_wf_no ...

  9. Elasticsearch零停机时间更新索引配置或迁移索引

    本文介绍Elasticsearch零宕机时间更新索引配置映射内容的方法,包括字段类型.分词器.分片数等.方法原理就是,利用别名机制,给索引配置别名,所有应用程序都通过别名访问索引.重建索引,通过索引原 ...

  10. 写在用Mac进行Java开发之前

    在用Mac进行开发之前,建议浏览以下几个概念. 1. 几个基础概念 - 计算机 计算机(computer)俗称电脑,发明者是约翰·冯·诺依曼,计算机是现代一种用于高速计算的电子计算机器,可以进行数值计 ...