hdu1754(splay)
给n个数,有两种操作 Q a b 询问区间[a,b]的最大值, U a b 将第a个数的值改成b
splay树的中序遍历是我们所维护的序列。如果要询问区间[a,b]的最大值,那么只要将第a-1个数旋转到根结点, 将第b+1个数旋转到根的右孩子,那么根的右孩子的左子树就是所要查询的区间。我们为每一个结点维护一个最大值,表示该以该结点为根的子树的最大值, 那么答案就是 Max[next[next[root][1]][0]];
为了防止越界, 比如要查询区间[1,n] 那么要将第0个数旋转到根结点,将第n+1个数旋转到根的右孩子, 但是却没有这两个数。 所以为了方便,在序列的两端加上两个数,这两个数比序列中的所有数都小, 所以并不影响答案。
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
const int N = + ;
int next[N][],pre[N],key[N],Max[N],sz[N],tot,root;
int a[N]; //如果更新第x个结点, 那么将第该结点splay到根,然后更新
/*
如果询问区间[a,b]的最大值, 那么将a-1 splay到root,将b+1旋到next[root][1] */
void newNode(int &rt, int fa, int k)
{
rt = ++tot;
next[rt][] = next[rt][] = ;
sz[rt] = ;
pre[rt] = fa;
key[rt] = k;
Max[rt] = k;//???????
}
void maintain(int rt)
{
Max[rt] = std::max(key[rt], std::max(Max[next[rt][]],Max[next[rt][]]));
sz[rt] = sz[next[rt][]] + sz[next[rt][]] + ;
}
void build(int &rt, int fa, int l, int r)
{
if(l>r) return;
int m =(l+r)>>;
newNode(rt,fa,a[m]);
build(next[rt][],rt,l,m-);
build(next[rt][],rt,m+,r);
maintain(rt);
}
void rotate(int x, int kind)
{
int y = pre[x];
next[y][!kind] = next[x][kind];
maintain(y);
pre[next[x][kind]] = y;
if(pre[y])
next[pre[y]][next[pre[y]][]==y] = x;
pre[x] = pre[y];
next[x][kind] = y;
pre[y] = x;
maintain(x);
}
int kth(int x, int k)
{
int tmp = sz[next[x][]] + ;
if(tmp==k)
return x;
if(tmp > k)
return kth(next[x][],k);
return kth(next[x][],k-tmp);
}
void splay(int x, int goal)
{
/*
只考虑左右旋的splay
while(pre[x]!=goal)
{
if(next[pre[x]][0]==x)
rotate(x,1);
else
rotate(x,0);
}
*/
while(pre[x]!=goal)
{
int y = pre[x];
if(pre[y]==goal)
{
if(next[y][]==x)
rotate(x,);
else
rotate(x,);
}
else
{
//kind 表示y是父亲的哪个儿子, 0 左,1 右
int kind = next[pre[y]][]==y;
if(next[y][kind]==x)//共线
{
rotate(y,!kind);
rotate(x,!kind);
}
else
{
rotate(x,kind);
rotate(x,!kind);
}
}
}
if(goal==)
root = x;
}
int main()
{
int n,m;
char opt[];
int x,y;
while(scanf("%d%d",&n,&m)!=EOF)
{
tot = ;
memset(next,,sizeof(next));
for(int i=;i<=n;++i)
scanf("%d",&a[i]);
newNode(root,,-);
newNode(next[root][],root,-);
build(next[next[root][]][],next[root][],,n);
maintain(next[root][]);
maintain(root);
while(m--)
{
scanf("%s%d%d",opt,&x,&y);
if(opt[]=='Q')
{
int tmp = kth(root,x);
splay(tmp,);
splay(kth(root,y+),root);
printf("%d\n",Max[next[next[root][]][]]);
}
else
{
splay(kth(root,x+),);
key[root] = Max[root] = y;
maintain(root);
}
}
}
return ;
}
hdu1754(splay)的更多相关文章
- hdu1754(splay tree 单点更新,成段查询)
题意就是简单的点更新,成段查询. splay tree 果真是常数比较大的log(n)操作. 比线段树还慢了这么多. // // main.cpp // splay // // Created by ...
- HDU 1754区间最值 & SPLAY
真是亲切的1754啊..第一道傻逼版的线段树做的是这个,后来学了zkw做的是这个,在后来决定打lrj线段树又打了一遍,如今再用splay和老朋友见面 从上到下依次为:加了读入优化的splay,sp ...
- Splay树再学习
队友最近可能在学Splay,然后让我敲下HDU1754的题,其实是很裸的一个线段树,不过用下Splay也无妨,他说他双旋超时,单旋过了,所以我就敲来看下.但是之前写的那个Splay越发的觉得不能看,所 ...
- BZOJ 1251: 序列终结者 [splay]
1251: 序列终结者 Time Limit: 20 Sec Memory Limit: 162 MBSubmit: 3778 Solved: 1583[Submit][Status][Discu ...
- [bzoj1269][AHOI2006文本编辑器editor] (splay模版题 or pb_ds [rope]大法)
Description 这些日子,可可不和卡卡一起玩了,原来可可正废寝忘食的想做一个简单而高效的文本编辑器.你能帮助他吗?为了明确任务目标,可可对“文本编辑器”做了一个抽象的定义: 文本:由0个或 ...
- splay最终模板
来自wjmzbmr的splay模板 #include<cstdio> #include<iostream> #include<algorithm> using na ...
- bzoj 3506 && bzoj 1552 splay
查最小值,删除,翻转... 显然splay啊... #include<iostream> #include<cstdio> #include<algorithm> ...
- 【splay】文艺平衡树 BZOJ 3223
Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 ...
- 【填坑】bzoj3224 splay裸题
人生第一道splay不出所料是一道裸题,一道水题,一道2k代码都不到的题 #include <cstdio> ,n,p,q; ],c[][],size[],sp[]; void rot(i ...
随机推荐
- Linux开发环境的搭建和使用——Linux 常用的命令使用
概要 视或电影中看到过类似的场景,黑客面对一个黑色的屏幕,上面飘着密密麻麻的字符,梆梆一顿敲,就完毕了窃取资料的任务. Linux 刚出世时没有什么图形界面.全部的操作全靠命令完毕.就如同电视里的黑客 ...
- Python - 定制pattern的string模板(template) 具体解释
定制pattern的string模板(template) 具体解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/28625179 ...
- 谁说程序员都是苦逼的——看看兄弟连上海S2班的点点滴滴
时间过的很快,上海校区第三期马上临近开班,第一期的学员也结束了自己第一个项目. 今天,2013.05.08日,我亲自参加了S01的第一个项目答辩,也为你们记录下了这样那样的一些时刻.其 ...
- java.text.MessageFormat格式化字符串时的小技巧
java.text.MessageFormat格式化字符串时的小技巧 public static void main(String[] args) throws InterruptedExceptio ...
- Ubuntu12.04创建 Eclipse launcher
Ubuntu 12.04 默认无法launcher Eclipse快捷图标到左侧Dash,需要手工配置,步骤如下: 1) 首先,创建并打开 ~/.local/share/applications/op ...
- linux—select具体解释
linux—select具体解释 select系统调用时用来让我们的程序监视多个文件句柄的状态变化的.程序会停在select这里等待,直到被监视的文件句柄有一个或多个发生了状态改变. 关于文件句柄,事 ...
- vs2008编译QT开源项目--太阳神三国杀源码分析(三) 皮肤
太阳神三国杀的界面很绚丽,界面上按钮的图标,鼠标移入移出时图标的变化,日志和聊天Widget的边框和半透明等效果,既可以通过代码来控制,也可以使用皮肤文件qss进行控制.下面我们分析一下三国杀的qss ...
- HDU 3549 Flow Problem(有向边网络流)
九野的博客,转载请注明出处 :http://blog.csdn.net/acmmmm/article/details/11221561 题意:T个测试数据 下面n,m表示n个点m条有向带权边 m条边 ...
- osc搜索引擎框架search-framework,TngouDB,gso,
项目目的:OSChina 实现全文搜索的简单封装框架 License: Public Domain 包含内容: 重建索引工具 -> IndexRebuilder.java 增量构建索引工具 -& ...
- csdn android视频播放器开发
http://blog.csdn.net/column/details/myvideo.html