题意:与区间查询点更新,点有20W个,询问区间的最大值。曾经用线段树,1000+ms,今天的伸展树,890没ms,差不多。

第一次学习伸展树,一共花了2个单位时间,感觉伸展树真很有用,也很好玩。现在只学了一点点。切个点更新试试。

大致思路:用编号(数组)作为树的键值建树,每插一个数,沿路节点更新最大值(每个结点有一个附加信息标记以之为子树的树所有点的最大值)。所以,查询时【i,j】,只要把i-1伸展到树根,把j+1伸展到I-1下面,那么j+1的左子树就是要的区间了!查该子树根值信息即可(特判端点)!同理,更新操作,只要把待更新的伸展到根,然后更新它,同时维护一下信息即可。

#include<iostream>
#include<cstdio>
using namespace std;
const int maxx=200010;
int a[maxx];int child[maxx][2];int fa[maxx];int maxo[maxx]; //a[i]是原来数组值,child左右孩子(0,1),maxo【i】是以序号i为根的子树(包括自身)的最大值。
int root=0;
void inline maintain(int n) //点被修改后,该点值的维护
{
maxo[n]=maxo[n]>a[n]?maxo[n]:a[n];
}
void inline rotate(int x,int f) //f=1右旋,f=0左旋
{
int y=fa[x];
maxo[x]=maxo[y]; //最大值的更新
maxo[y]=maxo[child[x][f]]>maxo[child[y][f]]?maxo[child[x][f]]:maxo[child[y][f]];
maintain(y); child[y][!f]=child[x][f]; //三次的重连线,注意顺序。
fa[child[x][f]]=y; if(fa[y])
{
if(y==child[fa[y]][0])
child[fa[y]][0]=x;
else
child[fa[y]][1]=x;
}
else
{
root=x;
}
fa[x]=fa[y]; child[x][f]=y;
fa[y]=x;
}
void splay(int n,int goal) //把序号为i的点转到点goal下面的孩子。
{
while(fa[n]!=goal) //一直左右旋即可
{
int y=fa[n];
rotate(n,child[y][0]==n?1:0);
}
}
void inline insert(int n) //插入来建树
{
int temp=root;
if(root==0) //根节点
{
root=n;
maxo[n]=n;
return ;
}
else
{
while(1)
{
maxo[temp]=maxo[temp]<a[n]?a[n]:maxo[temp];//插入时候维护最大值
if(n<temp) //左边
{
if(child[temp][0]==0)
{
child[temp][0]=n;
fa[n]=temp;
maxo[n]=a[n];
splay(n,0); //注意这里要伸展,否则建树就是一般的排序二叉树,会超时
return ;
}
temp=child[temp][0];
}
else //右边
{
if(child[temp][1]==0)
{
child[temp][1]=n;
fa[n]=temp;
maxo[n]=a[n];
splay(n,0);
return ;
}
temp=child[temp][1];
}
}
}
}
void update(int n,int x) //更新 ,把序号为n的值更新为x
{
splay(n,0);
a[n]=x;
maxo[n]=maxo[child[n][0]]>maxo[child[n][1]]?maxo[child[n][0]]:maxo[child[n][1]];
maintain(n);
}
void clear() //初始化
{
root=0;
for(int i=0;i<maxx;i++)
{
maxo[i]=child[i][0]=child[i][1]=fa[i]=0;
}
}
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
clear();
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
insert(i);
}
char q;int i,j;
while(m--)
{
getchar();
scanf("%c%d%d",&q,&i,&j);
if(q=='Q')
{ int ans=0;
if(i==1&&j!=n) //区间端点的特判
{
splay(j+1,0);
ans=maxo[child[j+1][0]];
}
else if(i!=1&&j==n)
{
splay(i-1,0);
ans=maxo[child[i-1][1]];
}
else if(i==1&&j==n)
{
ans=maxo[root];
}
else
{
splay(i-1,0);
splay(j+1,i-1);
ans=maxo[child[j+1][0]];
}
printf("%d\n",ans);
}
else
{
update(i,j);
}
}
}
return 0;
}

hdu 1754 splay tree伸展树 初战(单点更新,区间属性查询)的更多相关文章

  1. [转] Splay Tree(伸展树)

    好久没写过了,比赛的时候就调了一个小时,差点悲剧,重新复习一下,觉得这个写的很不错.转自:here Splay Tree(伸展树) 二叉查找树(Binary Search Tree)能够支持多种动态集 ...

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

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

  3. HDU 1754 I hate it 树状数组维护区间最大值

    Problem Description 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少.这让很多学生很反感. 不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写 ...

  4. HDU 3577 Fast Arrangement ( 线段树 成段更新 区间最值 区间最大覆盖次数 )

    线段树成段更新+区间最值. 注意某人的乘车区间是[a, b-1],因为他在b站就下车了. #include <cstdio> #include <cstring> #inclu ...

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

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

  6. POJ 3264-Balanced Lineup(段树:单点更新,间隔查询)

    Balanced Lineup Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 34522   Accepted: 16224 ...

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

    I Hate It                                                                             Time Limit: 90 ...

  8. SPOJ - QTREE(树链剖分+单点更新+区间最大值查询)

    题意:给出n个点n-1条边的树,有两个操作,一个是查询节点l到r的边的最大值,然后指定边的更改权值. 题解:差不多是树链剖分的模版题,注意每个点表示的边是连向其父亲节点的边. #include < ...

  9. Splay伸展树入门(单点操作,区间维护)附例题模板

    Pps:终于学会了伸展树的区间操作,做一个完整的总结,总结一下自己的伸展树的单点操作和区间维护,顺便给未来的自己总结复习用. splay是一种平衡树,[平均]操作复杂度O(nlogn).首先平衡树先是 ...

随机推荐

  1. python基础一 day11 装饰器复习

    # 复习# 讲作业# 装饰器的进阶 # functools.wraps # 带参数的装饰器 # 多个装饰器装饰同一个函数# 周末的作业 # 文件操作 # 字符串处理 # 输入输出 # 流程控制 # 装 ...

  2. CSS BEM 命名规范简介

    [前言] BEM 是一个简单又非常有用的命名约定.让你的前端代码更容易阅读和理解,更容易协作,更容易控制,更加健壮和明确,而且更加严密.这篇文章主要介绍了CSS BEM 命名规范简介(推荐)的相关资料 ...

  3. NoSQL 之 Morphia 操作 MongoDB

    上两篇文章:http://www.cnblogs.com/hoojo/archive/2011/06/01/2066426.html http://www.cnblogs.com/hoojo/arch ...

  4. ASP.NET 开发人员不必担心 Node 的五大理由

    哦别误会……我真的很喜欢 Node,而且我觉得它提出的概念和模式将在很长一段时间内,对服务端 Web 编程产生深远的影响.即使随着时间的推移 Node 过气了,我们肯定可以从下一个牛逼玩意身上或多或少 ...

  5. Ukulele 调音

    正常的持琴姿势时,从上到下依次是:4,3,2,1弦,音从上往下是:G,C,E,A: 3弦 - C - Do - D - Re 2弦 - E - Mi - F - Fa 4弦 - G -So 1弦 - ...

  6. MFC学习小结

    2019/1/13 视频来源 一.   MFC框架中一些重要的函数 1. InitInstance函数 应用程序类的一个虚函数,MFC应用程序的入口.初始化的作用. 2. PreCreateWindo ...

  7. Django REST framework 的功能

    1. 认证Authentication 方法一:在配置文件中配置全局默认的认证方案 REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ( 're ...

  8. (40)zabbix监控web服务器访问性能

    zabbix web监控介绍 在host列可以看到web(0),在以前的版本这项是独立出来的,这个主要实现zabbix对web性能的监控,通过它可以了解web站点的可用性以及性能. 最终将各项指标绘制 ...

  9. js解析器

    1>js的预解析 找var function 参数等 所有的变量,在正式运行代码前,都提前赋了一个值:未定义 所有的函数,在正式运行代码前,都是整个函数块. 遇到重名的:只留一个 如果变量与函数 ...

  10. VC++中char和TCHAR之间转换

    char:计算机编程语言(c.c++.java等)中可容纳单个字符的一种基本数据类型. TCHAR:为了满足Unicode编码,对char的扩展,即_T(“str”)表示TCHAR类型 C++支持两种 ...