题目描述

网上有许多题,就是给定一个序列,要你支持几种操作: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种操作,给出正确的回答。

样例输入

4 4
1 1 3 2
1 2 4 -1
2 1 3
3 2 4

样例输出

2
【数据范围】
N<=50000,M<=100000。
 
非旋转treap模板题,对于区间翻转和区间修改直接将修改区间断裂出来打上标记,像线段树一样遍历到点时再下传标记就好了。注意有负数。

#include<set>
#include<map>
#include<stack>
#include<queue>
#include<cmath>
#include<cstdio>
#include<vector>
#include<bitset>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
int x,y,z;
int n,m;
int k,L,R;
ll c;
int cnt;
int root;
int s[50010];
ll mx[50010];
int r[50010];
ll v[50010];
int ls[50010];
int rs[50010];
int size[50010];
ll a[50010];
int build(int rt)
{
r[++cnt]=rand();
size[cnt]=1;
return cnt;
}
void add(int rt,int val)
{
mx[rt]+=val;
a[rt]+=val;
v[rt]+=val;
}
void rotate(int rt)
{
swap(ls[rt],rs[rt]);
s[rt]^=1;
}
void pushup(int rt)
{
size[rt]=size[ls[rt]]+size[rs[rt]]+1;
mx[rt]=v[rt];
if(ls[rt])
{
mx[rt]=max(mx[rt],mx[ls[rt]]);
}
if(rs[rt])
{
mx[rt]=max(mx[rt],mx[rs[rt]]);
}
}
void pushdown(int rt)
{
if(s[rt])
{
if(ls[rt])
{
rotate(ls[rt]);
}
if(rs[rt])
{
rotate(rs[rt]);
}
s[rt]=0;
}
if(a[rt])
{
if(ls[rt])
{
add(ls[rt],a[rt]);
}
if(rs[rt])
{
add(rs[rt],a[rt]);
}
a[rt]=0; }
}
int merge(int x,int y)
{
if(!x||!y)
{
return x+y;
}
pushdown(x);
pushdown(y);
if(r[x]<r[y])
{
rs[x]=merge(rs[x],y);
pushup(x);
return x;
}
else
{
ls[y]=merge(x,ls[y]);
pushup(y);
return y;
}
}
void split(int rt,int k,int &x,int &y)
{
if(!rt)
{
x=y=0;
return ;
}
pushdown(rt);
if(size[ls[rt]]<k)
{
x=rt;
split(rs[rt],k-size[ls[rt]]-1,rs[x],y);
}
else
{
y=rt;
split(ls[rt],k,x,ls[y]);
}
pushup(rt);
}
int main()
{
srand(20011112);
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
root=merge(root,build(i));
}
while(m--)
{
scanf("%d",&k);
scanf("%d%d",&L,&R);
if(k==1)
{
scanf("%lld",&c);
split(root,L-1,x,y);
split(y,R-L+1,y,z);
add(y,c);
root=merge(merge(x,y),z);
}
else if(k==2)
{
split(root,L-1,x,y);
split(y,R-L+1,y,z);
rotate(y);
root=merge(merge(x,y),z);
}
else
{
split(root,L-1,x,y);
split(y,R-L+1,y,z);
printf("%lld\n",mx[y]);
root=merge(merge(x,y),z);
}
}
}

BZOJ1251序列终结者——非旋转treap的更多相关文章

  1. BZOJ1552[Cerc2007]robotic sort&BZOJ3506[Cqoi2014]排序机械臂——非旋转treap

    题目描述 输入 输入共两行,第一行为一个整数N,N表示物品的个数,1<=N<=100000. 第二行为N个用空格隔开的正整数,表示N个物品最初排列的编号. 输出 输出共一行,N个用空格隔开 ...

  2. [bzoj3173]最长上升子序列_非旋转Treap

    最长上升子序列 bzoj-3173 题目大意:有1-n,n个数,第i次操作是将i加入到原有序列中制定的位置,后查询当前序列中最长上升子序列长度. 注释:1<=n<=10,000,开始序列为 ...

  3. BZOJ5063旅游——非旋转treap

    题目描述 小奇成功打开了大科学家的电脑. 大科学家打算前往n处景点旅游,他用一个序列来维护它们之间的顺序.初 始时,序列为1,2,...,n. 接着,大科学家进行m次操作来打乱顺序.每次操作有6步: ...

  4. BZOJ3223文艺平衡树——非旋转treap

    此为平衡树系列第二道:文艺平衡树您需要写一种数据结构,来维护一个有序数列,其中需要提供以下操作: 翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1 ...

  5. 平衡树及笛卡尔树讲解(旋转treap,非旋转treap,splay,替罪羊树及可持久化)

    在刷了许多道平衡树的题之后,对平衡树有了较为深入的理解,在这里和大家分享一下,希望对大家学习平衡树能有帮助. 平衡树有好多种,比如treap,splay,红黑树,STL中的set.在这里只介绍几种常用 ...

  6. 4923: [Lydsy1706月赛]K小值查询 平衡树 非旋转Treap

    国际惯例的题面:这种维护排序序列,严格大于的进行操作的题都很套路......我们按照[0,k],(k,2k],(2k,inf)分类讨论一下就好.显然第一个区间的不会变化,第二个区间的会被平移进第一个区 ...

  7. 非旋转Treap

    Treap是一种平衡二叉树,同时也是一个堆.它既具有二叉查找树的性质,也具有堆的性质.在对数据的查找.插入.删除.求第k大等操作上具有期望O(log2n)的复杂度.     Treap可以通过节点的旋 ...

  8. 非旋转Treap:用运行时间换调试时间的有效手段

    非旋转Treap:用运行时间换调试时间的有效手段   Hello大家好,我们今天来聊一聊非旋转Treap. 相信各位或多或少都做过些序列上的问题.如果水题我们考虑暴力:不强制在线我们可能用过莫队和待修 ...

  9. [bzoj3196][Tyvj1730]二逼平衡树_树套树_位置线段树套非旋转Treap/树状数组套主席树/权值线段树套位置线段树

    二逼平衡树 bzoj-3196 Tyvj-1730 题目大意:请写出一个维护序列的数据结构支持:查询给定权值排名:查询区间k小值:单点修改:查询区间内定值前驱:查询区间内定值后继. 注释:$1\le ...

随机推荐

  1. 【Codeforces 1109C 】Sasha and a Patient Friend

    Codeforces 1109 C 题意:现在有个碗,每时每刻其中的水量都会加一个整数(可以为负). 给\(n\)个询问,询问有\(3\)种类型: \(1\ t\ s\):将从第\(t\)秒开始水量增 ...

  2. Daily Sentence(英语每日一句)

    1.When you want to give up, remember why you started. 当你想要放弃的时候,请记住当初你为何而开始. 2.It does not do to dwe ...

  3. C# 深浅复制 MemberwiseClone(转载)

    最近拜读了大话设计模式:原型模式,该模式主要应用C# 深浅复制来实现的!关于深浅复制大家可参考MSDN:https://docs.microsoft.com/zh-cn/dotnet/api/syst ...

  4. Vue-Vue列表渲染v-for

    v-for 指令需要以 site in sites 形式的特殊语法 一.v-for 循环数组 HTML代码 <div id="app"> <ul> < ...

  5. 如何实现.net程序的进程注入

    原文:如何实现.net程序的进程注入   如何实现.net程序的进程注入                                   周银辉 进程注入比较常见,比如用IDE调试程序以及一些Sp ...

  6. odoo订餐系统之订单相关知识点理解

    1.对重载函数name_get的理解 第一,此函数位于Model基类中,返回值是一个list列表,列表中的每个值是如(key,value)形式的键值对,此处为(id,name). 第二,在自己的Mod ...

  7. 大话设计模式之工厂模式 C#

    学无止境,精益求精 十年河东,十年河西,莫欺少年穷 学历代表你的过去,能力代表你的现在,学习代表你的将来 大话设计模式一书中第一个开讲的设计模式是简单工厂模式,关于简单工厂模式大家可参考鄙人的博客:代 ...

  8. 【nodejs】让nodejs像后端mvc框架(asp.net mvc)一样处理请求--目录(8/8 完结)

    为什么要做这个 在使用nodejs开发过程中,总是发现需要做很多重复性的体力劳动,且因为自身是服务端程序员出身,感觉有一些服务端好的东西其实可以在nodejs上得到应用并能提高一些开发工作效率. 本系 ...

  9. [BUAA软工]第二次博客作业---结对编程

    [BUAA软工]结对作业 项目 内容 这个作业属于哪个课程 北航软工 这个作业的要求在哪里 2019年软件工程基础-结对项目作业 我在这个课程的目标是 学习如何以团队的形式开发软件,提升个人软件开发能 ...

  10. selective search

    1.引言:图像的物体识别主要有两个步骤:定位.分类.在分类的过程中,需要对图像中文物体的区域划分出来.传统的方法是利用滑窗,一个窗口一个窗口得选择,将之与目标进行比较,确定物体的位置. 为了降低搜索空 ...