题目大意

网上有许多题,就是给定一个序列,要你支持几种操作:A、B、C、D。一看另一道题,又是一个序列要支持几种操作:D、C、B、A。尤其是我们这里的某人,出模拟试题,居然还出了一道这样的,真是没技术含量……这样 我也出一道题,我出这一道的目的是为了让大家以后做这种题目有一个“库”可以依靠,没有什么其他的意思。这道题目 就叫序列终结者吧。【问题描述】 给定一个长度为N的序列,每个序列的元素是一个整数(废话)。要支持以下三种操作: 1. 将 [L, R] 这个区间内的所有数加上 V。 2. 将 [L,R] 这个区间翻转,比如 1 2 3 4 变成 4 3 2 1。3. 求 [L,R] 这个区间中的最大值。最开始所有元素都是 0。

第一行两个整数 N,M。M 为操作个数。以下 M 行,每行最多四个整数,依次为 K, L, R, V。K 表示是第几种操作,如果不是第 1 种操作则 K 后面只有两个数。对于每个第3种操作,给出正确的回答。

【数据范围】N<=50000,M<=100000。

做法分析

这题还真不能用 线段树 做,Splay 是一个不错的选择

对于操作 1 将所有 [L, R] 中的数加上一个常量,可以对 Splay 树中的节点增加一个 add 域,表示以该节点为根中序遍历所得的数列中每个数要增加 add,每次执行的时候,先将 L-1 旋转到根,再把 R+1 旋转成根的儿子节点,那么,[L, R] 区间的数列就在 R+1 的左子树中了,对 R+1 的左儿子执行更新操作即可,类似于线段树的懒操作

对于操作 2 将所有 [L, R] 中的数翻转,可以对 Splay 树中的节点增加一个 rev 域,表示以该节点为根中序遍历所得的数列是否需要翻转,更新的时候还是和操作 1 一样,将 L-1 旋转到根,R+1 旋转成为 L-1 的孩子,直接对 R+1 的左儿子更新

对于操作 3,增加一个 Max 域,表示以该节点为根中序遍历得到的数列中最大值是多少,询问时,将 L-1 旋转到根,R+1 旋转成 L-1 的孩子,询问 R-1 的左儿子的 Max 即可

这里说一点细节:由于是维护数列,且涉及到区间翻转操作,所以还要增加一个 Size 域,表示以它为根的中序遍历得到的数列的个数是多少,用它来实现数列中的定位

由于涉及到翻转和统一加权操作,pushDown 和 pushUp 操作一定要想好在哪些地方需要执行

参考代码

 #include <iostream>
#include <cstring>
#include <cstdio> using namespace std; const int N=, INF=0x7fffffff; struct Splay_Tree {
struct Node {
int val, Max, add, Size, son[];
bool rev;
void init(int _val) {
val=Max=_val, Size=;
add=rev=son[]=son[]=;
}
} T[N];
int fa[N], root; void pushUp(int x) {
T[x].Max=T[x].val, T[x].Size=;
if(T[x].son[]) {
T[x].Max=max(T[x].Max, T[T[x].son[]].Max);
T[x].Size+=T[T[x].son[]].Size;
}
if(T[x].son[]) {
T[x].Max=max(T[x].Max, T[T[x].son[]].Max);
T[x].Size+=T[T[x].son[]].Size;
}
} void pushDown(int x) {
if(x==) return;
if(T[x].add) {
if(T[x].son[]) {
T[T[x].son[]].val+=T[x].add;
T[T[x].son[]].Max+=T[x].add;
T[T[x].son[]].add+=T[x].add;
}
if(T[x].son[]) {
T[T[x].son[]].val+=T[x].add;
T[T[x].son[]].Max+=T[x].add;
T[T[x].son[]].add+=T[x].add;
}
T[x].add=;
}
if(T[x].rev) {
if(T[x].son[]) T[T[x].son[]].rev^=;
if(T[x].son[]) T[T[x].son[]].rev^=;
swap(T[x].son[], T[x].son[]);
T[x].rev=;
}
} void Rotate(int x, int kind) {
int y=fa[x], z=fa[y];
T[y].son[!kind]=T[x].son[kind], fa[T[x].son[kind]]=y;
T[x].son[kind]=y, fa[y]=x;
T[z].son[T[z].son[]==y]=x, fa[x]=z;
pushUp(y);
} void Splay(int x, int goal) {
if(x==goal) return;
while(fa[x]!=goal) {
int y=fa[x], z=fa[y];
pushDown(z), pushDown(y), pushDown(x);
int rx=T[y].son[]==x, ry=T[z].son[]==y;
if(z==goal) Rotate(x, rx);
else {
if(rx==ry) Rotate(y, ry);
else Rotate(x, rx);
Rotate(x, ry);
}
}
pushUp(x);
if(goal==) root=x;
} int Select(int pos) {
int u=root;
pushDown(u);
while(T[T[u].son[]].Size!=pos) {
if(pos<T[T[u].son[]].Size) u=T[u].son[];
else {
pos-=T[T[u].son[]].Size+;
u=T[u].son[];
}
pushDown(u);
}
return u;
} void update(int L, int R, int val) {
int u=Select(L-), v=Select(R+);
Splay(u, );
Splay(v, u);
T[T[v].son[]].Max+=val;
T[T[v].son[]].val+=val;
T[T[v].son[]].add+=val;
} void Reverse(int L, int R) {
int u=Select(L-), v=Select(R+);
Splay(u, );
Splay(v, u);
T[T[v].son[]].rev^=;
} int query(int L, int R) {
int u=Select(L-), v=Select(R+);
Splay(u, );
Splay(v, u);
return T[T[v].son[]].Max;
} int build(int L, int R) {
if(L>R) return ;
if(L==R) return L;
int mid=(L+R)>>, sL, sR;
T[mid].son[]=sL=build(L, mid-);
T[mid].son[]=sR=build(mid+, R);
fa[sL]=fa[sR]=mid;
pushUp(mid);
return mid;
} void init(int n) {
T[].init(-INF), T[].init(-INF), T[n+].init(-INF);
for(int i=; i<=n+; i++) T[i].init();
root=build(, n+), fa[root]=;
fa[]=, T[].son[]=root, T[].Size=;
}
}; Splay_Tree hehe; int main() {
int n, m;
scanf("%d%d", &n, &m);
hehe.init(n);
for(int i=, a, b, c, d; i<m; i++) {
scanf("%d", &a);
if(a==) {
scanf("%d%d%d", &b, &c, &d);
hehe.update(b, c, d);
}
else if(a==) {
scanf("%d%d", &b, &c);
hehe.Reverse(b, c);
}
else {
scanf("%d%d", &b, &c);
printf("%d\n", hehe.query(b, c));
}
}
return ;
}

BZOJ 1251

题目链接 & AC 通道

BZOJ 1251 序列终结者

BZOJ 1251 序列终结者(Splay)的更多相关文章

  1. BZOJ 1251: 序列终结者 [splay]

    1251: 序列终结者 Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 3778  Solved: 1583[Submit][Status][Discu ...

  2. bzoj 1251序列终结者 splay 区间翻转,最值,区间更新

    序列终结者 Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 4594  Solved: 1939[Submit][Status][Discuss] De ...

  3. BZOJ 1251: 序列终结者

    1251: 序列终结者 Time Limit: 20 Sec  Memory Limit: 162 MB Submit: 3773  Solved: 1579 [Submit][Status][Dis ...

  4. bzoj 1251: 序列终结者 平衡树,fhqtreap

    链接 https://www.lydsy.com/JudgeOnline/problem.php?id=1251 思路 好简单的模板题 不过还是wrong了好几发 叶子节点要注意下,不能使用 遇到就不 ...

  5. 【BZOJ】1251: 序列终结者(splay)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1251 不行..为什么写个splay老是犯逗,这次又是null的mx没有赋值-maxlongint.. ...

  6. 1251. 序列终结者【平衡树-splay】

    Description 网上有许多题,就是给定一个序列,要你支持几种操作:A.B.C.D.一看另一道题,又是一个序列 要支持几种操作:D.C.B.A.尤其是我们这里的某人,出模拟试题,居然还出了一道这 ...

  7. 【BZOJ1251】序列终结者 Splay

    一道模板题,一直没发现自己的快速读入读不了负数,我竟然能活到现在真是万幸. #include <iostream> #include <cstdio> #define inf ...

  8. CODEVS 4655 序列终结者-splay(区间更新、区间翻转、区间最值)

    4655 序列终结者  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 大师 Master 题解       题目描述 Description 网上有许多题,就是给定一个序列,要 ...

  9. [bzoj1251]序列终结者——splay

    题目大意 网上有许多题,就是给定一个序列,要你支持几种操作:A.B.C.D.一看另一道题,又是一个序列 要支持几种操作:D.C.B.A.尤其是我们这里的某人,出模拟试题,居然还出了一道这样的,真是没技 ...

随机推荐

  1. [游戏模版12] Win32 稳定定时

    >_<:The last time,we learned how to use timer to make the picture run and change show,but some ...

  2. C# 通过SerialPort简单调用串口

    问题 最近比较经常使用串口进行发送以及传输数据,但是笔者在刚开始接触SerialPort类时,对于Write之后去Read数据的时候,由于设备上面还没有返回数据,读取到的只能是空值.然而,再进行下一次 ...

  3. Wijmo 2016 V2 强势发布!

    Angular 2 支持 Wijmo 对 Angular 2 提供了全面的支持.我们一直在紧跟Angular 2 开发团队的步伐,对其发布的最新候选版本提供支持. 了解更多关于Angular 2 的支 ...

  4. struts2学习笔记之一:基本简介

    Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个Servlet,在MVC设计模式中,Struts2作为控制器来建立模型与视图的数据交互(所有的访问都会被控制器操作控制)   ...

  5. iOS开发之静态库(六)—— 时空之争

    前面的所有试验中,我们的静态库都支持了所有可能的指令集(i386, x86_64, armv7, armv7s, arm64),最大限 度的匹配了所有可能运行该代码的设备,使代码在当前存在的几乎所有i ...

  6. MySQL完整性语言

    文章为作者原创,未经许可,禁止转载.    -Sun Yat-sen University 冯兴伟 实验3:完整性语言 完整性语言实验包含3个实验项目,其中2个必修项目,1个选修项目.该实验的各个实验 ...

  7. Azure Stack如何解决混合云的种种挑战

    微软希望能够通过Azure Stack来帮助企业连接他们的私有云和公共云.但这仍然是一项进行中的工作. 大多数企业都不愿意将所有IT运营都放到公有云中.相反,他们希望可以灵活的在这两个共享的基础架构即 ...

  8. linux之cp/scp命令+scp命令详解(转)

    名称:cp 使用权限:所有使用者 使用方式: cp [options] source dest cp [options] source... directory 说明:将一个档案拷贝至另一档案,或将数 ...

  9. svn 403 Forbidden

    用svn client的时候出现这么一个问题,客户端能正常check out,但是在check in(commit,mkdir等)的时候出错了: Server sent unexpected retu ...

  10. 实用的插件:跨浏览器复制jQuery-zclip

    Query-zclip是一个复制内容到剪贴板的jQuery插件,使用它我们不用考虑不同浏览器和浏览器版本之间的兼容问题.jQuery-zclip插件需要Flash的支持,使用时记得安装Adobe Fl ...