bzoj3173 Splay 维护前缀中的最大值
大致题意:
有一个空序列,依次插入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 维护前缀中的最大值的更多相关文章
- 【BZOJ 3729】3729: Gty的游戏 (Splay维护dfs序+博弈)
未经博主同意不得转载 3729: Gty的游戏 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 448 Solved: 150 Description ...
- BZOJ1014[JSOI2008]火星人prefix(splay维护hash)
Description 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam,我们将这个字符串的各个字符予以标号:序号: 1 2 3 4 5 6 7 ...
- bzoj3786星系探索(splay维护dfs序)
Description 物理学家小C的研究正遇到某个瓶颈. 他正在研究的是一个星系,这个星系中有n个星球,其中有一个主星球(方便起见我们默认其为1号星球),其余的所有星球均有且仅有一个依赖星球.主星球 ...
- 51Nod 1277 字符串中的最大值 ( KMP && DP )
题意 : 一个字符串的前缀是指包含该字符第一个字母的连续子串,例如:abcd的所有前缀为a, ab, abc, abcd.给出一个字符串S,求其所有前缀中,字符长度与出现次数的乘积的最大值.例如:S ...
- 51Nod 1277 字符串中的最大值(KMP,裸题)
1277 字符串中的最大值 题目来源: Codility 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 一个字符串的前缀是指包含该字符第一个字母的连续子串,例如: ...
- 51nod 1277 字符串中的最大值
题目链接 51nod 1277 字符串中的最大值 题解 对于单串,考虑多串的fail树,发现next数组的关系形成树形结构 建出next树,对于每一个前缀,他出现的次数就是他子树的大小 代码 #inc ...
- 51nod 1277字符串中的最大值(拓展kmp)
题意: 一个字符串的前缀是指包含该字符第一个字母的连续子串,例如:abcd的所有前缀为a, ab, abc, abcd. 给出一个字符串S,求其所有前缀中,字符长度与出现次数的乘积的最大值. 题解 ...
- HNOI2004宠物收养所(splay维护二叉搜索树模板题)
描述 最近,阿Q开了一间宠物收养所.收养所提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物.每个领养者都希望领养到自己满意的宠物,阿Q根据领养者的要求通过他自己发明的一个特殊的公式,得出该领 ...
- 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 ...
随机推荐
- 冲量:momentum
参见:http://www.jianshu.com/p/58b3fe300ecb,这个博客里有冲量的python实现的代码和讲解 “冲量”这个概念源自于物理中的力学,表示力对时间的积累效应. 在普通的 ...
- sql 内联,左联,右联,全联
联合查询效率较高,以下例子来说明联合查询(内联.左联.右联.全联)的好处: T1表结构(用户名,密码) userid (int) username varchar(20) password varc ...
- Linux 2440 LCD 控制器【转】
转自:http://www.cnblogs.com/armlinux/archive/2011/01/14/2396864.html 嵌入式Linux之我行,主要讲述和总结了本人在学习嵌入式linux ...
- FastDFS集群部署
之前介绍过关于FastDFS单机部署,详见博文:FastDFS+Nginx(单点部署)事例 下面来玩下FastDFS集群部署,实现高可用(HA) 服务器规划: 跟踪服务器1[主机](Tracker S ...
- 使用DOS访问数据库详解
今天突发奇想,想是否可以用DOS命令来操作本地数据库或者连接其他外地数据库,网上搜了很多教程比较繁琐,自己想写一篇文章详细叙述一下,也为以后复习做点备份. 工具: 电脑 win7 64bit MySQ ...
- 栈应用之 后缀表达式计算 (python 版)
栈应用之 后缀表达式计算 (python 版) 后缀表达式特别适合计算机处理 1. 中缀表达式.前缀表达式.后缀表达式区别 中缀表达式:(3 - 5) * (6 + 17 * 4) / 3 17 ...
- 转:localStorage 还能这么用
地址:https://iammapping.com/the-other-ways-to-use-localstorage/ localStorage 还能这么用 HTML5中 Web Storage ...
- 用HTML+CSS实现--折叠效果
下图是一个Accordion组件,请用HTML+CSS实现其UI,并用面向对象的思路把折叠效果JS实现.如果能用纯css的方式实现其折叠效果更佳.PS/这是小米15年的一道校招笔试题,无意间看到就实现 ...
- springMVC源码分析--HttpMessageConverter写write操作(三)
上一篇博客springMVC源码分析--HttpMessageConverter参数read操作中我们已经简单介绍了参数值转换的read操作,接下来我们介绍一下返回值的处理操作.同样返回值的操作操作也 ...
- NFS服务简介
NFS服务简介 NFS是Network File System的缩写,即网络文件系统.NFS是由Sun开发并发展起来的一项用于在不同机器,不同操作系统之间通过网络互相分享各自的文件.NFS serve ...