真是亲切的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. 三、jQuery--jQuery基础--jQuery基础课程--第4章 jQuery表单选择器

    1.:input表单选择器 如何获取表单全部元素?:input表单选择器可以实现,它的功能是返回全部的表单元素,不仅包括所有<input>标记的表单元素,而且还包括<textarea ...

  2. TCP 四次握手

    TCP协议中的三次握手和四次挥手(图解) http://blog.csdn.net/whuslei/article/details/6667471/

  3. MVC部分视图(Partial View)

    分部视图,也就是整体视图的一部分.单个视图页面展示在整体页面之上,使用步骤如下 1.创建视图数据也就是viewmodel public class FooterViewModel { public s ...

  4. python多进程程序之间交换数据的两种办法--Queue和Pipe

    合在一起作的测试. #!/usr/bin/env python # -*- coding: utf-8 -*- import multiprocessing import random import ...

  5. html5移动Web开发实战

    1.解决横竖屏字体大小变化 html{ -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; text-size-adjust:100 ...

  6. 7-15ALL、 ANY、SOME子查询

    ALL:所有 ANY:部分 SOME:与ANY相同,使用ANY的地方都可以用SOME替换. >ALL:父查询中列的值必须大于子查询返回的值列表的每一个值. >ANY:父查询中的返回值必须大 ...

  7. WPF中查看PDF文件

    需要打开PDF文件时,我们第一印象就是使用Adobe Reader.在开发中,经常会遇到需要展示PDF文件的需求.我们会借助于Adobe Reader的Active控件来实现.不过这需要客户的机器上安 ...

  8. 深入分析JavaWeb 技术内幕

    1,通过浏览器请求一个资源,会发生以下几种过程 1) http的解析过程,包括对于http请求头和响应头中指令(控制用户浏览器的渲染行为和 服务器的执行逻辑)的解析 2)DNS的解析过程(根据域名获取 ...

  9. VS2010和matlab2010混合编程中char16_t重定义的问题

    原因是VS2010中的yvals.h添加了char16_t的定义,而Matlab的matrix.h也包含对char16_t的定义,所以同时包含这两个头文件的话,会导致重复定义char16_t的错误.只 ...

  10. 利用Aspose.Word控件和Aspose.Cell控件,实现Word文档和Excel文档的模板化导出

    我们知道,一般都导出的Word文档或者Excel文档,基本上分为两类,一类是动态生成全部文档的内容方式,一种是基于固定模板化的内容输出,后者在很多场合用的比较多,这也是企业报表规范化的一个体现. 我的 ...