1.注意在 split 和 merge时要特判一下边界, 否则就会出现边界错误的情况。

2.随时都要维护父指针。
3.在更新 maxv
 和翻转标记时要判一下左右儿子是否都存在。

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 100000 + 3;
int f[maxn], ch[maxn][2], n,m,numv[maxn], maxv[maxn], siz[maxn], tag[maxn], root, cnt , lazy[maxn];
struct Operation
{
inline int get(int x){ return ch[f[x]][1] == x; }
inline void pushdown(int x)
{
if(tag[x])
{
swap(ch[ch[x][0]][0],ch[ch[x][0]][1]);
swap(ch[ch[x][1]][0],ch[ch[x][1]][1]);
if(ch[x][0]) tag[ch[x][0]] ^= 1;
if(ch[x][1]) tag[ch[x][1]] ^= 1;
tag[x] = 0;
}
if(lazy[x])
{
if(ch[x][0]) maxv[ch[x][0]] += lazy[x], lazy[ch[x][0]] += lazy[x], numv[ch[x][0]] += lazy[x];
if(ch[x][1]) maxv[ch[x][1]] += lazy[x], lazy[ch[x][1]] += lazy[x], numv[ch[x][1]] += lazy[x];
lazy[x] = 0;
}
}
inline void pushup(int x)
{
siz[x] = siz[ch[x][0]] + siz[ch[x][1]] + 1;
maxv[x] = numv[x];
if(ch[x][0]) maxv[x] = max(maxv[x], maxv[ch[x][0]]);
if(ch[x][1]) maxv[x] = max(maxv[x], maxv[ch[x][1]]);
}
inline void rotate(int x)
{
int old = f[x], oldf = f[old], which = get(x);
ch[old][which] = ch[x][which ^ 1], f[ch[old][which]] = old;
ch[x][which ^ 1] = old, f[old] = x, f[x] = oldf;
if(oldf) ch[oldf][ch[oldf][1] == old] = x;
pushup(old); pushup(x);
}
inline void splay(int x,int &tar)
{
int a = f[tar];
for(int fa; (fa = f[x]) != a; rotate(x))
if(f[fa] != a) rotate(get(x) == get(fa) ? fa : x);
tar = x;
}
inline int findx(int x, int top)
{
int cur = top;
while(x > 0)
{
pushdown(cur);
int ls = ch[cur][0], rs = ch[cur][1];
if(siz[ls] + 1 == x) return cur;
if(siz[ls] >= x) cur = ls;
else x -= siz[ls] + 1, cur = rs;
}
return 0;
}
inline void split(int &a,int nums,int &b)
{
if(nums == 0)
{
b = a, a = 0; return ;
}
if(nums == siz[a])
{
b = 0; return ;
}
int u = findx(nums, a);
splay(u, a);
b = ch[a][1];
f[ch[a][1]] = 0, ch[a][1] = 0,
pushup(a);
}
inline void merge(int &a,int b)
{
if(!a) { a = b; return ;}
splay(findx(siz[a], a), a);
ch[a][1] = b, f[b] = a;
pushup(a);
}
void build(int l,int r,int &o,int fa)
{
if(l > r) return ;
o = ++cnt;
f[o] = fa, siz[o] = 1;
int mid = (l + r) >> 1;
build(l, mid - 1, ch[o][0], o);
build(mid + 1, r, ch[o][1], o);
pushup(o);
}
}T;
int main()
{
//freopen("input.txt","r",stdin);
scanf("%d%d",&n,&m);
T.build(1, n, root, 0);
while(m--)
{
int ops, l , r, v = 0;
scanf("%d%d%d",&ops,&l,&r);
int a = 0, b = 0;
T.split(root, l - 1, a);
T.split(a, r - l + 1, b);
if(ops == 1)
{
scanf("%d",&v);
maxv[a] += v, lazy[a] += v, numv[a] += v;
T.pushup(a);
}
if(ops == 2)
{
swap(ch[a][0], ch[a][1]);
tag[a] ^= 1;
}
if(ops == 3)
{
printf("%d\n",maxv[a]);
}
T.merge(root, a);
T.merge(root, b);
}
return 0;
}

  

序列终结者 Splay的更多相关文章

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

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

  2. 【BZOJ1251】序列终结者 Splay

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

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

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

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

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

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

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

  6. bzoj1251 序列终结者(splay)

    人生第一发splay,写得巨丑,最后忘记了push_down以后要将子节点maintain 9k代码不忍直视 #define NDEBUG #include<cstdio> #includ ...

  7. BZOJ 1251 序列终结者(Splay)

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

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

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

  9. bzoj1251 序列终结者(Splay Tree+懒惰标记)

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

随机推荐

  1. BZOJ 3329 Xorequ (数位DP、矩阵乘法)

    手动博客搬家: 本文发表于20181105 23:18:54, 原地址https://blog.csdn.net/suncongbo/article/details/83758728 题目链接 htt ...

  2. cxdbImage以及图像显示

    把pdf以及图像存入数据库,然后根据需要显示出来.在处理的过程中,不同类型的图像格式有其不同的类,如果这个概念不清楚,就会绕一个很大的圈子. MyJPEG : TJPEGImage ; mypng : ...

  3. 读取com口接收byte数据的处理

    procedure Tfrm_CheckCloth.cnrs232ReceiveData(Sender: TObject; Buffer: Pointer; BufferLength: Word); ...

  4. Feign 负载均衡

    一.是什么 Feign 是一个声明式 WebService 客户端.使用 Feign 能让编写 Web Service 客户端更加简单,他的使用方法是定义一个接口,然后在上面添加注解.同时也支持 JA ...

  5. Future和Callable的使用

    应用场景 财务成本核算.可能会有多个耗时的步骤.如果顺序执行是非常慢的.再相互数据获取数据不依赖的情况下可以使用Future并行执行 public class FutureTest implement ...

  6. 零基础学python-2.16 列表解析

    这一节聊聊强大的列表解析 主要就是在一行里面赋值给列表 以下我们举两个样例: 上面的样例我们引入了range函数,他主要作用是在一定范围里面取整数值 我来解释一下中括号中面的那一句:x**2 for ...

  7. android高速上手(二)android开发环境搭建及hello world

    基本了解了java语法,下一步.我们一起开启hello world的神奇之旅. (一)android开发环境搭建 之前搭建android开发环境是件很费力的事情,下载Eclipse.安装ADT等,现在 ...

  8. 公司须要内部的地图服务,准备自己去开发可是成本太高,如今有没有专门为企业提供GIS地图开发的产品呀?大概价格多少?

    公司须要内部的地图服务,准备自己去开发可是成本太高,如今有没有专门为企业提供GIS地图开发的产品呀?大概价格多少?

  9. session理解

    Session,底层的实现就是一个Map<集合>,有些Data在Server内存中,APP要分层.Data在各个层之间肯定要以一种形态传递(泛型),之前Servlet dao.getLis ...

  10. Ubuntu安装及ubuntu系统使用菜岛教程

    Ubuntu是一款广受欢迎的开源Linux发行版,和其他Linux操作系统相比,Ubuntu非常易用,和Windows相容性很好,非常适合Windows用户的迁移,在其八年的成长过程中已经获得了两千多 ...