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 < ...
随机推荐
- 通过I2C总线向EEPROM中写入数据,记录开机次数
没买板子之前,用protues画过电路图,实现了通过i2c总线向EEPROM中写入和读出数据. 今天,在自己买的板子上面写关于i2c总线的程序,有个地方忘了延时,调程序的时候很蛋疼.下面说说我对I2c ...
- 创建共享内存函数CreateFileMapping()详解
测试创建和打开文件映射的时候老是得到"句柄无效"的错误, 仔细看了MSDN以后才发觉是函数认识不透, 这里把相关的解释翻译出来 HANDLE CreateFileMapping( ...
- PHP与最丑的后台管理系统
第二天阿Q到公司还是比较早,同事只有阿梅在,阿Q坐在椅子上旋转来旋转去,有点像个小孩子.公司有书柜,书柜上放了好几本很新的php的书,.net的书反倒比较少而且显得老旧.阿Q起身走过去拿了本php翻了 ...
- sql里条件is null 在thinkphp里
$map['字段名'] = array('exp',' is NULL'); 譬如:$condition['url'] = array('exp',' is NULL');
- opencv for python 之 突出点检测
opencv下载地址:http://sourceforge.net/projects/opencvlibrary/files/opencv-win/2.4.3/OpenCV-2.4.3.exe/dow ...
- [jobdu]不用加减乘除做加法
使用异或和与,模拟机器的加法.http://blog.csdn.net/htyurencaotang/article/details/11125415 #include <iostream> ...
- More on 1Password’s Components
Stefan van As of 1Password fame sent me a more exhaustive list of the libraries and tools used in 1P ...
- C# Json处理日期和Table
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Ru ...
- 编写 Objective-C 代码
如果您未曾开发过 iOS 或 Mac OS X 平台的程序,那就需要开始了解它们的首要程序设计语言 Objective-C.Objective-C 并不是一种很难的语言,如果能花一点时间学习,相信您会 ...
- SQL中取当前记录的ID----->SCOPE_IDENTITY()
SQL Server 2000中,有三个比较类似的功能:他们分别是:SCOPE_IDENTITY.IDENT_CURRENT 和 @@IDENTITY,它们都返回插入到 IDENTITY 列中的值.I ...