HDU 1754区间最值 & SPLAY
真是亲切的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的更多相关文章
- hdu 1754 I Hate It (splay tree伸展树)
hdu 1754 I Hate It 其实我只是来存一下我的splay模板的..请大牛们多多指教 #include<stdio.h> #include<string.h> #i ...
- HDU 1754 I Hate It (Splay 区间操作)
题目大意 维护一个序列,支持两种操作 操作一:将第x个元素的值修改为y 操作二:询问区间[x,y]内的元素的最大值 解题分析 splay的区间操作,事先加入两个编号最小和最大的点防止操作越界. 具体的 ...
- hdu 1754 I Hate It (线段树功能:单点更新和区间最值)
版权声明:本文为博主原创文章.未经博主同意不得转载.vasttian https://blog.csdn.net/u012860063/article/details/32982923 转载请注明出处 ...
- HDU 1754 I Hate It(线段树单点替换+区间最值)
I Hate It [题目链接]I Hate It [题目类型]线段树单点替换+区间最值 &题意: 本题目包含多组测试,请处理到文件结束. 在每个测试的第一行,有两个正整数 N 和 M ( 0 ...
- HDU 1754 I Hate It(线段树单点更新区间最值查询)
I Hate It Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- 【HDU】1754 I hate it ——线段树 单点更新 区间最值
I Hate It Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total S ...
- HDU 1754 I Hate It(线段树之单点更新 区间最值查询)
I Hate It Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total S ...
- HDU 1754 I Hate It<区间最值 单点修改>
I Hate It Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total S ...
- HDU 1754.I Hate It-完全版线段树(单点替换、区间最值)
HDU1754.I Hate It 直接模板就可以了 代码: //B #include<iostream> #include<cstdio> #include<cstri ...
随机推荐
- React Native官方DEMO
官方给我们提供了UIExplorer项目,这里边包含React Native的基本所有组件的使用介绍和方法. 运行官方DEMO步骤如下 安装react native环境 React Native项目源 ...
- logstash之multiline插件,匹配多行日志
在外理日志时,除了访问日志外,还要处理运行时日志,该日志大都用程序写的,比如log4j.运行时日志跟访问日志最大的不同是,运行时日志是多行,也就是说,连续的多行才能表达一个意思. 在filter中,加 ...
- Linux 通过os进程pid找到端口号
[root@xxxx conf]# netstat -lutpn|grep tcp /java tcp /java tcp /java tomcat 监听的一些端口
- CLR via C#(02)-基元类型、引用类型、值类型
http://www.cnblogs.com/qq0827/p/3281150.html 一. 基元类型 编译器能够直接支持的数据类型叫做基元类型.例如int, string等.基元类型和.NET框架 ...
- (1)Underscore.js入门
1. Underscore对象封装 Underscore并没有在原生的JavaScript对象原型中进行扩展,而是像jQuery一样,将数据封装在一个自定义对象中(下文中称"Undersco ...
- Unity依赖注入使用
构造器注入(Constructor Injection):IoC容器会智能地选择选择和调用适合的构造函数以创建依赖的对象.如果被选择的构造函数具有相应的参数,IoC容器在调用构造函数之前会自定义创建相 ...
- Android ANR分析(三)
http://www.jianshu.com/p/8964812972be http://stackoverflow.com/questions/704311/android-how-do-i-inv ...
- Pyqt 设置 背景颜色和背景图片、 QPalette 调色板 与QPainter 画板区别 、 不规则图片
设置 背景颜色和背景图片 首先设置autoFillBackground属性为真然后定义一个QPalette对象设置QPalette对象的背景属性(颜色或图片)最后设置QWidget对象的Palette ...
- 【网络资料】如何优雅地使用Sublime Text3
如何优雅地使用Sublime Text3 Sublime Text:一款具有代码高亮.语法提示.自动完成且反应快速的编辑器软件,不仅具有华丽的界面,还支持插件扩展机制,用她来写代码,绝对是一种享受.相 ...
- HDU 2896 病毒侵袭(AC自动机)
病毒侵袭 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...