hdu 1754 I Hate It (splay tree伸展树)
其实我只是来存一下我的splay模板的。。请大牛们多多指教
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std ; const int maxn = 222222 ; int son[2][maxn] , col[maxn] , fa[maxn] , size[maxn] , val[maxn] ;
int tot ;
int num[maxn] ; void new_node () {
size[tot] = 1 ;
fa[tot] = son[0][tot] = son[1][tot] = -1 ;
val[tot] = col[tot] = 0 ;
tot ++ ;
} void update ( int rt ) {
size[rt] = 1 ;
col[rt] = val[rt] ;
if ( son[0][rt] != -1 )
size[rt] += size[son[0][rt]] , col[rt] = max ( col[rt] , col[son[0][rt]] ) ;
if ( son[1][rt] != -1 )
size[rt] += size[son[1][rt]] , col[rt] = max ( col[rt] , col[son[1][rt]] ) ;
} int build ( int l , int r ) {
if ( l > r ) return -1 ;
int mid = ( l + r ) >> 1 ;
new_node () ;
int temp = tot - 1 ;
val[temp] = num[mid] ;
son[0][temp] = build ( l , mid - 1 ) ;
if ( son[0][temp] != -1 ) fa[son[0][temp]] = temp ;
son[1][temp] = build ( mid + 1 , r ) ;
if ( son[1][temp] != -1 ) fa[son[1][temp]] = temp ;
update ( temp ) ;
return temp ;
} void rot ( int rt , int c ) {
int y = fa[rt] , z = fa[y] ;
son[!c][y] = son[c][rt] ;
if ( son[c][rt] != -1 ) fa[son[c][rt]] = y ;
fa[rt] = z ;
if ( z != -1 ) {
if ( y == son[0][z] ) son[0][z] = rt ;
else son[1][z] = rt ;
}
son[c][rt] = y , fa[y] = rt ;
update ( y ) ;
} void splay ( int rt , int to ) {
while ( fa[rt] != to ) {
if ( fa[fa[rt]] == to ) {
if ( rt == son[0][fa[rt]] ) rot ( rt , 1 ) ;
else rot ( rt , 0 ) ;
}
else {
int y = fa[rt] , z = fa[y] ;
if ( rt == son[0][y] ) {
if ( y == son[0][z] ) rot ( y , 1 ) , rot ( rt , 1 ) ;
else rot ( rt , 1 ) , rot ( rt , 0 ) ;
}
else {
if ( y == son[1][z] ) rot ( y , 0 ) , rot ( rt , 0 ) ;
else rot ( rt , 0 ) , rot ( rt , 1 ) ;
}
}
}
update ( rt ) ;
/*为什么只要在最后更新rt节点呢?因为在旋转的过程中,fa[rt]总是旋到rt下面的
所以在旋转的时候,我们不断的更新fa[rt],而不需要一直更新rt,只要在splay之后更新rt就好了
*/
} int find ( int rt , int key ) {
int cnt = 0 ;
if ( son[0][rt] != -1 ) cnt = size[son[0][rt]] ;
if ( cnt + 1 == key ) return rt ;
if ( cnt >= key ) return find ( son[0][rt] , key ) ;
return find ( son[1][rt] , key - cnt - 1 ) ;
} int main () {
int n , m , i , j , k , a , b ;
char op[11] ;
while ( scanf ( "%d%d" , &n , &m ) != EOF ) {
for ( i = 1 ; i <= n ; i ++ ) scanf ( "%d" , &num[i] ) ;
tot = 0 ;
int root = build ( 0 , n + 1 ) , temp ;
while ( m -- ) {
scanf ( "%s%d%d" , op , &a , &b ) ;
a ++ , b ++ ;//因为建树的时候,把0也建进去了,但实际上0是不在原数组中的,所有往后推移一位
if ( op[0] == 'U' ) {
temp = find ( root , a ) ;
splay ( temp , -1 ) ;
root = temp ;
val[root] = b - 1 ;
// update ( root ) ;
//这里为什么不用更新rt呢?因为对于size的值是不会变的,而val值已经更新了,而对于col值,下次是splay时,肯定会更新掉的
}
else {
temp = find ( root , a - 1 ) ;
splay ( temp , -1 ) ;
root = temp ;
temp = find ( root , b + 1 ) ;
splay ( temp , root ) ;
printf ( "%d\n" , col[son[0][temp]] ) ;
}
}
}
}
hdu 1754 I Hate It (splay tree伸展树)的更多相关文章
- [转] Splay Tree(伸展树)
好久没写过了,比赛的时候就调了一个小时,差点悲剧,重新复习一下,觉得这个写的很不错.转自:here Splay Tree(伸展树) 二叉查找树(Binary Search Tree)能够支持多种动态集 ...
- hdu 1754 splay tree伸展树 初战(单点更新,区间属性查询)
题意:与区间查询点更新,点有20W个,询问区间的最大值.曾经用线段树,1000+ms,今天的伸展树,890没ms,差不多. 第一次学习伸展树,一共花了2个单位时间,感觉伸展树真很有用,也很好玩.现在只 ...
- HDU 1754区间最值 & SPLAY
真是亲切的1754啊..第一道傻逼版的线段树做的是这个,后来学了zkw做的是这个,在后来决定打lrj线段树又打了一遍,如今再用splay和老朋友见面 从上到下依次为:加了读入优化的splay,sp ...
- HDU 1890 Robotic Sort (splay tree)
Robotic Sort Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tota ...
- [置顶] hdu 4699 2个栈维护 or 伸展树
hdu 4699 Editor 题意:对一个数列进行操作,光标位置后面插入一个权值为x的数,删除光标前的那个数,光标左移一位,光标右移一位,求到k位置的最大的前缀和.. 注意这里的k是在光标之前的, ...
- 【模板】Splay(伸展树)普通平衡树(数据加强版)/洛谷P6136
题目链接 https://www.luogu.com.cn/problem/P6136 题目大意 需要写一种数据结构,来维护一些非负整数( \(int\) 范围内)的升序序列,其中需要提供以下操作: ...
- HDU 1754 I Hate It (Splay 区间操作)
题目大意 维护一个序列,支持两种操作 操作一:将第x个元素的值修改为y 操作二:询问区间[x,y]内的元素的最大值 解题分析 splay的区间操作,事先加入两个编号最小和最大的点防止操作越界. 具体的 ...
- Splay(伸展树)/HDU6873
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=6873 题目大意 给定一组 \(n\) 列的方块,每列方块数 \(b_i\) ,现有 \(q\) 次操作 ...
- HDU 4718 The LCIS on the Tree(树链剖分)
Problem Description For a sequence S1, S2, ... , SN, and a pair of integers (i, j), if 1 <= i < ...
随机推荐
- mysql 的存储引擎
注意:mysql开发很少显示使用外键,MyISAM可以定义外键,但不起作用. mysql最新的5.6版本支持,全文索引.
- Linux df 命令
Linux df 命令 df(disk free)功能说明:显示磁盘的相关信息.语 法:df [-ahHiklmPT][--block-size=<区块大小>][-t <文件系统类型 ...
- [转载]C#.NET中Dns类的常用方法及说明
IP是一种普遍应用于因特网.允许不同主机能够相互找到对方的寻址协议.IP地址由4个十进制的数字号码所组成,而每一个号码的值介于0~255之间,它虽然解决了网络上计算机的识别问题,但是IP地址确不容易记 ...
- csuoj 1352: New Sorting Algorithm
因为每个元素都是移动到比它小1位的元素的后面: 这样的话以后的一定就可以把他们两个打包: 所以用这种方法最多扫一遍就可以了: 但是最小的那个数要不要移动呢? 如果最小的数后面的数都是升序的,那么一直扫 ...
- 对加密方式(公钥私钥)的形象理解(以http和https为例)
https其实就是建构在SSL/TLS之上的 http协议,所以要比较https比http多用多少服务器资源,主要看SSL/TLS本身消耗多少服务器资源. http使用TCP 三次握手建立连接,客户端 ...
- Android中改变dialog的显示的位置和大小
private void setDialogSize(Dialog dg) { Window dialogWindow = dg.getWindow(); WindowManager.LayoutPa ...
- Form.block Trigger DML常规写法
Block的数据源是View的,如果想操作数据,需要注意在以下几个Trigger里面写代码: 一般建议创建View的时候包含rowid字段. on-lock: select inventory_ite ...
- Wpf配置文件属性
public MainWindow() { InitializeComponent(); this.WindowState = Properties.Settings.Default.WindowSt ...
- PHPCMS 2008 SQL注入漏洞
漏洞版本: PHPCMS 2008 漏洞描述: escape()方法无法过滤$genre变量进行二次URL编码,导致SQL注入漏洞产生. <* 参考 http://www.yunsec.net/ ...
- Wordpress prettyPhoto插件跨站脚本漏洞
漏洞名称: Wordpress prettyPhoto插件跨站脚本漏洞 CNNVD编号: CNNVD-201311-413 发布时间: 2013-11-28 更新时间: 2013-11-28 危害等级 ...