真是亲切的1754啊。。第一道傻逼版的线段树做的是这个,后来学了zkw做的是这个,在后来决定打lrj线段树又打了一遍,如今再用splay和老朋友见面

    从上到下依次为:加了读入优化的splay,splay,加了inline的splay,边读入边建树的lrj线段树,zkw线段树,以及线段树初体验

题意

  单点修改询问区间最值。

SOL:

  平衡树真是优美的植物,像陀螺通过不断的优雅的旋转体现自身的平衡与美感。

  对于splay的区间问题,我们利用序号来建树,当要查询一个区间时,我们把这个区间左端点的前一个点旋到根,那么这个区间就都在根的右子树中,再将右端点的后一个点旋到根的右儿子,那么整段区间就都在根的右儿子的左儿子上了。整个过程利用BST的性质非常显然。当然为了防止越界我们把整段序列向右平移一格,便于维护。

  对于这样的询问,splay与线段树没有什么区别,线段树是分割线段,而splay是取出线段,然后标记、最值、和什么的都一样了,所以线段树能实现的splay都能实现(除了可持久化。

  当然对比上图,我们还是能看出它们之间的优劣。。zkw线段树继承了树状数组的优点,代码短效率高——但是貌似细节巨多。。我现在也忘得差不多了。。lrj线段树由于是nlgn的建树所以看起来稍微慢一点,实际上的效率应该在正常水平左右,打了一些注释所以代码长度显得长一些。 而splay。。。内存我多开了很多没有用的数组显得大一点。代码长度尽管以前没有用现在这么多的头文件。。但由于操作非常多尽管已经尽力把splay写得非常紧凑但还是要长处不少。

  在速度上实现得和线段树差不多,看起来也挺好。

CODE:

/*==========================================================================
# Last modified: 2016-02-19 15:23
# Filename: hdu1754.cpp
# Description:
==========================================================================*/
#define me AcrossTheSky
#include <cstdio>
#include <cmath>
#include <ctime>
#include <string>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm> #include <set>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#define lowbit(x) (x)&(-x)
#define INF 1070000000
#define FOR(i,a,b) for((i)=(a);(i)<=(b);(i)++)
#define FORP(i,a,b) for(int i=(a);i<=(b);i++)
#define FORM(i,a,b) for(int i=(a);i>=(b);i--)
#define ls(a,b) (((a)+(b)) << 1)
#define rs(a,b) (((a)+(b)) >> 1)
#define maxn 300000
#define getlc(a) ch[(a)][0]
#define getrc(a) ch[(a)][1]
using namespace std;
typedef long long ll;
typedef unsigned long long ull; template<class T> inline
void read(T& num) {
bool start=false,neg=false;
char c;
num=0;
while((c=getchar())!=EOF) {
if(c=='-') start=neg=true;
else if(c>='0' && c<='9') {
start=true;
num=num*10+c-'0';
} else if(start) break;
}
if(neg) num=-num;
}
/*==================split line==================*/
int root;
int n,m;
int fa[maxn],ch[maxn][2],_max[maxn],v[maxn],s[maxn],a[maxn];
int cnt=0;
int null;
inline void updata(int node){
s[node]=1+s[getlc(node)]+s[getrc(node)];
_max[node]=max(v[node],max(_max[getlc(node)],_max[getrc(node)]));
}
inline void rotate(int x){
int p=fa[x],q=fa[p],d=ch[p][1]==x;
fa[ch[p][d]=ch[x][d^1]]=p; updata(p);
fa[ch[x][d^1]=p]=x;
fa[x]=q;
if (q){
if (ch[q][0]==p) ch[q][0]=x;
else if (ch[q][1]==p) ch[q][1]=x;
}
updata(x);
}
inline void splay(int x,int &aim){
for(int y;(y=fa[x])!=aim;rotate(x))
if (fa[y]!=aim) rotate((getlc(y)==x)==(getlc(fa[y])==y)?y:x);
if (aim==0) root=x;
updata(x);
}
inline void change(int node,int x){
splay(node,null);
v[node]=x;
updata(node);
}
inline void query(int l,int r){
splay(l-1,null);
splay(r+1,root);
printf("%d\n",_max[getlc(getrc(root))]); }
inline int build(int sz){
if (sz<=0) return 0;
int t=build(sz/2),node=++cnt;
fa[ch[node][0]=t]=node;
fa[ch[node][1]=build(sz-sz/2-1)]=node;
if (node==1 || node==n+2) v[node]=-INF;
else v[node]=a[node];
updata(node);
return node;
}
int main(){
while (scanf("%d%d",&n,&m)!=EOF){
cnt=0;
memset(_max,0,sizeof(_max));
memset(fa,0,sizeof(fa));
memset(v,0,sizeof(v));
FORP(i,1,n) read(a[i+1]);
null=0;
root=build(n+2);
FORP(i,1,m){
char s[2]; scanf("%s",s); int x,y; read(x); read(y);
if (s[0]=='Q') query(x+1,y+1);
else change(x+1,y);
}
}
}

HDU 1754区间最值 & SPLAY的更多相关文章

  1. hdu 1754 I Hate It (splay tree伸展树)

    hdu 1754 I Hate It 其实我只是来存一下我的splay模板的..请大牛们多多指教 #include<stdio.h> #include<string.h> #i ...

  2. HDU 1754 I Hate It (Splay 区间操作)

    题目大意 维护一个序列,支持两种操作 操作一:将第x个元素的值修改为y 操作二:询问区间[x,y]内的元素的最大值 解题分析 splay的区间操作,事先加入两个编号最小和最大的点防止操作越界. 具体的 ...

  3. hdu 1754 I Hate It (线段树功能:单点更新和区间最值)

    版权声明:本文为博主原创文章.未经博主同意不得转载.vasttian https://blog.csdn.net/u012860063/article/details/32982923 转载请注明出处 ...

  4. HDU 1754 I Hate It(线段树单点替换+区间最值)

    I Hate It [题目链接]I Hate It [题目类型]线段树单点替换+区间最值 &题意: 本题目包含多组测试,请处理到文件结束. 在每个测试的第一行,有两个正整数 N 和 M ( 0 ...

  5. HDU 1754 I Hate It(线段树单点更新区间最值查询)

    I Hate It Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  6. 【HDU】1754 I hate it ——线段树 单点更新 区间最值

    I Hate It Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total S ...

  7. HDU 1754 I Hate It(线段树之单点更新 区间最值查询)

    I Hate It Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total S ...

  8. HDU 1754 I Hate It<区间最值 单点修改>

    I Hate It Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total S ...

  9. HDU 1754.I Hate It-完全版线段树(单点替换、区间最值)

    HDU1754.I Hate It 直接模板就可以了 代码: //B #include<iostream> #include<cstdio> #include<cstri ...

随机推荐

  1. max number of threads [1024] for user [lish] likely too low, increase to at least [2048]

    # cat /etc/security/limits.d/-nproc.conf # Default limit for number of user's processes to prevent # ...

  2. Java并发编程中的阻塞和中断

    >>线程的状态转换 线程的状态转换是线程控制的基础,下面这张图片非常直观的展示了线程的状态转换: 线程间的状态转换: 1. 新建(new):新创建了一个线程对象.2. 可运行(runnab ...

  3. Delphi之DLL知识学习1---什么是DLL

    DLL(动态链接库)是程序模块,它包括代码.数据或资源,能够被其他的Windows 应用程序共享.DLL的主要特点之一是应用程序可以在运行时调入代码执行,而不是在编译时链接代码,因此,多个应用程序可以 ...

  4. centos安装oracle 11g 完全图解

    摘要: 说明: Linux服务器操作系统:CentOS 5.8 32位(注意:系统安装时请单独分区/data用来安装oracle数据库) Linux服务器IP地址:192.168.21.150 Ora ...

  5. Sencha Architect 安装与使用

    http://www.sencha.com/products/touch/ Sencha SDK Tools Advanced JavaScript and CSS Project Build Too ...

  6. [Nodejs]十分钟快速编写简单静态文件服务器

    学了几天Nodejs 后我又干上了前端的活.这次遇到的问题是,我想在不同的设备上方便的查看我编写的网页,很自然的就想到要是能在本地搭建一个简单的http服务器的话,那局域网内的所有设备都可以访问了,这 ...

  7. Solr入门之(3)常用概念说明(持续补充):

    由于solr底层使用lucene,所以很多概念与lucene相同,下面是几个常用的概念: * Document:一个要进行索引的单元,相当于数据库的一行纪录,任何想要被索引的数据,都必须转化为Docu ...

  8. 团队作业-第二周-SRS文档

    移动课堂点名的用例图:

  9. html5 离线存储 worker

    html5 离线存储 <!DOCTYPE html> <html manifest="cache.manifest"> <!--manifest存储- ...

  10. C#屏幕截图

    今天通过C#来实现一个简单的屏幕截图功能.实现思路,获取鼠标按下去的位置和鼠标左键释放的位置,计算这个区域的宽度和高度.然后通过 Graphics.CopyFromScreen 方法便可以获取到屏幕截 ...