题目描述

给出一个初始序列fA1;A2;:::Ang,要求你编写程序支持如下操作: 1. ADDxyD:给子序列fAx:::Ayg的每个元素都加上D。例如对f1,2, 3,4,5g执行"ADD 241" 会得到f1,3,4,5,5g。 2. REVERSExy:将子序列fAx:::Ayg翻转。例如对f1,2,3,4,5g执 行"REVERSE 24"会得到f1,4,3,2,5g。 3. REVOLVExyT:将子序列fAx:::Ayg旋转T个单位。例如, 对f1,2,3,4,5g执行"REVOLVE 242"会得到f1,3,4,2,5g。 4. INSERTxP:在Ax后插入P。例如,对f1,2,3,4,5g执行"INSERT 24"会得到f1,2,4,3,4,5g。 5. DELETEx:删去Ax。例如,对f1,2,3,4,5g执行"DELETE 2"会得 到f1,3,4,5g。 6. MINxy:查询子序列fAx:::Ayg中的最小元素。例如,对于序列f1, 2,3,4,5g,询问"MIN 24"的返回应为2。

输入

第一行包含一个整数n,表示初始序列的长度。 以下n行每行包含一个整数,描述初始的序列。 接下来一行包含一个整数m,表示操作的数目。 以下m行每行描述一个操作。

输出

对于所有"MIN"操作,输出正确的答案,每行一个。

样例输入

5
1
2
3
4
5
2
ADD 2 4 1
MIN 4 5

样例输出

5

提示

输入、输出以及中间运算结果均不会超过32位整数。
对于30%的数据,n;m 6 1000;
对于100%的数据,n;m 6 100000。

 
序列终结者加强版,注意旋转操作的T可能大于区间长因此要取模,其他操作比较常规,插入删除直接断裂开之后在中间删掉或者加入;区间操作将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 cnt;
int n,m;
int root;
int L,R,C;
int w,x,y,z;
char ch[16];
int a[300010];
int s[300010];
int r[300010];
int v[300010];
int mn[300010];
int ls[300010];
int rs[300010];
int size[300010];
int build(int val)
{
int rt=++cnt;
v[rt]=val;
size[rt]=1;
r[rt]=rand();
mn[rt]=val;
return rt;
}
void rotate(int rt)
{
swap(ls[rt],rs[rt]);
s[rt]^=1;
}
void add(int rt,int val)
{
a[rt]+=val;
mn[rt]+=val;
v[rt]+=val;
}
void pushup(int rt)
{
size[rt]=size[ls[rt]]+size[rs[rt]]+1;
mn[rt]=v[rt];
if(ls[rt])
{
mn[rt]=min(mn[rt],mn[ls[rt]]);
}
if(rs[rt])
{
mn[rt]=min(mn[rt],mn[rs[rt]]);
}
}
void pushdown(int rt)
{
if(s[rt])
{
if(ls[rt])
{
rotate(ls[rt]);
}
if(rs[rt])
{
rotate(rs[rt]);
}
s[rt]^=1;
}
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(20020419);
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&x);
root=merge(root,build(x));
}
scanf("%d",&m);
while(m--)
{
scanf("%s",ch);
if(ch[0]=='A')
{
scanf("%d%d%d",&L,&R,&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(ch[0]=='R'&&ch[3]=='E')
{
scanf("%d%d",&L,&R);
split(root,L-1,x,y);
split(y,R-L+1,y,z);
rotate(y);
root=merge(merge(x,y),z);
}
else if(ch[0]=='R'&&ch[3]=='O')
{
scanf("%d%d%d",&L,&R,&C);
C%=(R-L+1);
if(C==0)
{
continue;
}
C=(R-L+1)-C;
split(root,L-1,x,y);
split(y,R-L+1,y,z);
split(y,C,y,w);
root=merge(merge(x,merge(w,y)),z);
}
else if(ch[0]=='I')
{
scanf("%d%d",&L,&C);
split(root,L,x,y);
root=merge(merge(x,build(C)),y);
}
else if(ch[0]=='D')
{
scanf("%d%d",&L,&C);
split(root,L-1,x,y);
split(y,1,y,z);
root=merge(x,z);
}
else
{
scanf("%d%d",&L,&R);
split(root,L-1,x,y);
split(y,R-L+1,y,z);
printf("%d\n",mn[y]);
root=merge(merge(x,y),z);
}
}
}

BZOJ1895Pku3580 supermemo——非旋转treap的更多相关文章

  1. [bzoj1895][Pku3580]supermemo_非旋转Treap

    supermemo bzoj-1895 Pku-3580 题目大意:给定一个n个数的序列,需支持:区间加,区间翻转,区间平移,单点插入,单点删除,查询区间最小值. 注释:$1\le n\le 6.1\ ...

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

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

  3. 关于非旋转treap的学习

    非旋转treap的操作基于split和merge操作,其余操作和普通平衡树一样,复杂度保证方式与旋转treap差不多,都是基于一个随机的参数,这样构出的树树高为\(logn\) split 作用:将原 ...

  4. [Codeforces702F]T-Shirts——非旋转treap+贪心

    题目链接: Codeforces702F 题目大意:有$n$种T恤,每种有一个价格$c_{i}$和品质$q_{i}$且每种数量无限.现在有$m$个人,第$i$个人有$v_{i}$元,每人每次会买他能买 ...

  5. BZOJ5063旅游——非旋转treap

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

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

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

  7. BZOJ3224普通平衡树——非旋转treap

    题目: 此为平衡树系列第一道:普通平衡树您需要写一种数据结构,来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个)3. 查询x数的排名(若有多个相同的数, ...

  8. [NOIP]2017列队——旋转treap/非旋转treap

    Sylvia 是一个热爱学习的女孩子.  前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia所在的方阵中有n × m名学生,方阵的行数为 n,列数为m.  为了便 ...

  9. BZOJ3729Gty的游戏——阶梯博弈+巴什博弈+非旋转treap(平衡树动态维护dfs序)

    题目描述 某一天gty在与他的妹子玩游戏.妹子提出一个游戏,给定一棵有根树,每个节点有一些石子,每次可以将不多于L的石子移动到父节点,询问将某个节点的子树中的石子移动到这个节点先手是否有必胜策略.gt ...

随机推荐

  1. lesson 4:凯撒密码问题

    一·问题描述 二·解决过程 1.设计思路 ①人机交互界面 ②加密函数(将字符串的每一个字符提取出来,通过对字符的阿斯克码值进行运算操作实现加密过程,特殊的特殊对待) ③解密函数(与加密函数算法类似) ...

  2. 如何控制docker的CPU和内存份额

    1.内存:docker run -it -m 200M --memory-swap=300M progrium/stress --vm 1 --vm-bytes 500M 刚开始会报错: docker ...

  3. mqtt 客户端 基于Python

    这几天一直在搞安全通信,微信小程序,反向代理等等,为了能让自己对整个系统做到把控,主要是需要了解每一个细节的地方,所以今天花了3个小时的时间学习了Python,因为我要用它来做Http和WebSock ...

  4. 51单片机开发板(W25Q16学习)

    教程资料 链接:https://pan.baidu.com/s/142JRSPisQO2Cu6VZ2Y5YrQ 密码:eom0 今天测试开发板的W25Q16(16Mbit--Flash)写一篇文章备忘 ...

  5. GIT 分支管理:多人协作

    当你从远程仓库克隆时,实际上Git自动把本地的master分支和远程的master分支对应起来了,并且,远程仓库的默认名称是origin. 要查看远程库的信息,用git remote: $ git r ...

  6. (转)Ubuntu无法找到add-apt-repository问题的解决方法

    原文 网上查了一下资料,原来是需要 python-software-properties 于是 apt-get install python-software-properties 除此之外还要安装 ...

  7. .Net并行编程(一)-TPL之数据并行

    前言 许多个人计算机和工作站都有多个CPU核心,可以同时执行多个线程.利用硬件的特性,使用并行化代码以在多个处理器之间分配工作. 应用场景 文件批量上传 并行上传单个文件.也可以把一个文件拆成几段分开 ...

  8. 手机H5移动端WEB资源整合之meta标签

    一.相关网站使用meta的实例 youku首页的Meta设置: <meta charset="utf-8"> <meta http-equiv="X-U ...

  9. Linux下IP SAN共享存储操作记录

    一.简单介绍SAN,即存储区域网络(storage area network and SAN protocols),它是一种高速网络实现计算机与存储系统之间的数据传输.常见的分类是FC-SAN和IP- ...

  10. Nginx反向代理的简单实现

    1)nginx的反向代理:proxy_pass2)nginx的负载均衡:upstream 下面是nginx的反向代理和负载均衡的实例: 负载机:A机器:103.110.186.8/192.168.1. ...