supermemo bzoj-1895 Pku-3580

题目大意:给定一个n个数的序列,需支持:区间加,区间翻转,区间平移,单点插入,单点删除,查询区间最小值。

注释:$1\le n\le 6.1\cdot 10^6$。


想法

这数据范围给的我真是醉了。

显然用平衡树,这里用非旋转Treap,题目让你干什么你就干什么。

区间加:撕出子树区间后打标记维护区间加。

区间翻转:撕出子树区间后打标记维护区间翻转。

区间平移:相当于两段相邻区间交换,所以撕成四部分:左边,第一个区间,第二个区间,右边。然后按照左边,第二个区间,第一个区间,右边合并即可。

单点插入:将一个点当成一个非旋转Treap,在插入位置左右撕开后将这个点放进去然后合上。

单点删除:同理,删除位置左,删除节点,右撕开后,不管这个点,直接把左边右边合上。

最后,附上丑陋的代码... ...

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 1210010
using namespace std;
struct Node
{
int ls,rs; int val,key;
int size; int add,rev;
int minn;
}a[N]; int tot;
struct par{int x,y;};
inline void pushup(int x)
{
int ls=a[x].ls,rs=a[x].rs;
a[x].size=1; a[x].minn=a[x].val;
if(ls) a[x].size+=a[ls].size,a[x].minn=min(a[x].minn,a[ls].minn);
if(rs) a[x].size+=a[rs].size,a[x].minn=min(a[x].minn,a[rs].minn);
}
inline void pushdown(int x)
{
int ls=a[x].ls,rs=a[x].rs;
if(a[x].rev)
{
if(ls) a[ls].rev^=1,swap(a[ls].ls,a[ls].rs);
if(rs) a[rs].rev^=1,swap(a[rs].ls,a[rs].rs);
a[x].rev=0;
}
if(a[x].add)
{
if(ls) a[ls].add+=a[x].add,a[ls].minn+=a[x].add,a[ls].val+=a[x].add;
if(rs) a[rs].add+=a[x].add,a[rs].minn+=a[x].add,a[rs].val+=a[x].add;
a[x].add=0;
}
}
int merge(int x,int y)
{
if(!x||!y) return x|y;
pushdown(x); pushdown(y);
if(a[x].key>a[y].key)
{
a[x].rs=merge(a[x].rs,y); pushup(x);
return x;
}
else
{
a[y].ls=merge(x,a[y].ls); pushup(y);
return y;
}
}
par split(int x,int k)
{
if(!k) return (par){0,x};
pushdown(x);
int ls=a[x].ls,rs=a[x].rs;
if(k==a[ls].size)
{
a[x].ls=0; pushup(x);
return (par){ls,x};
}
else if(k==a[ls].size+1)
{
a[x].rs=0; pushup(x);
return (par){x,rs};
}
else if(k<a[ls].size)
{
par t=split(ls,k);
a[x].ls=t.y; pushup(x);
return (par){t.x,x};
}
else
{
par t=split(rs,k-a[ls].size-1);
a[x].rs=t.x; pushup(x);
return (par){x,t.y};
}
}
inline int newnode(int val)
{
tot++; a[tot].val=a[tot].minn=val;
a[tot].ls=a[tot].rs=0;
a[tot].size=1; a[tot].key=rand()*rand();
a[tot].rev=a[tot].add=0;
return tot;
}
inline void update(int x,int val)
{
a[x].add+=val; a[x].minn+=val; a[x].val+=val;
}
inline void rev(int x)
{
a[x].rev^=1; swap(a[x].ls,a[x].rs);
}
int insert(int x,int k,int val)
{
par t=split(x,k);
return merge(t.x,merge(newnode(val),t.y));
}
void output(int x)
{
int ls=a[x].ls,rs=a[x].rs;
if(ls) output(ls);
printf("%d ",a[x].val);
if(rs) output(rs);
}
int main()
{
// freopen("1895.in","r",stdin);
// freopen("1895.out","w",stdout);
srand(19260817);
int n; cin >> n ; int root=1; int x; scanf("%d",&x); root=newnode(x);
for(int i=2;i<=n;i++)
{
scanf("%d",&x);
root=merge(root,newnode(x));
}
int y,z; char opt[100];
int m; cin >> m ; for(int i=1;i<=m;i++)
{
scanf("%s",opt+1);
if(opt[1]=='A')
{
scanf("%d%d",&x,&y);
par t1=split(root,x-1);
par t2=split(t1.y,y-x+1);
scanf("%d",&z);
update(t2.x,z);
root=merge(t1.x,merge(t2.x,t2.y));
}
else if(opt[1]=='R'&&opt[4]=='E')
{
scanf("%d%d",&x,&y);
par t1=split(root,x-1);
par t2=split(t1.y,y-x+1);
rev(t2.x);
root=merge(t1.x,merge(t2.x,t2.y));
}
else if(opt[1]=='R'&&opt[4]=='O')
{
scanf("%d%d%d",&x,&y,&z);
par t1=split(root,x-1);
par t2=split(t1.y,y-x+1);
par t3=split(t2.x,a[t2.x].size-(z%a[t2.x].size));
root=merge(t1.x,merge(merge(t3.y,t3.x),t2.y));
}
else if(opt[1]=='I')
{
scanf("%d%d",&x,&y);
y=newnode(y);
par t=split(root,x);
root=merge(t.x,merge(y,t.y));
}
else if(opt[1]=='D')
{
scanf("%d",&x);
par t1=split(root,x-1);
par t2=split(t1.y,1);
root=merge(t1.x,t2.y);
}
else if(opt[1]=='M')
{
scanf("%d%d",&x,&y);
par t1=split(root,x-1);
par t2=split(t1.y,y-x+1);
printf("%d\n",a[t2.x].minn);
root=merge(t1.x,merge(t2.x,t2.y));
}
}
return 0;
}

小结:非旋转Treap就是比splay优越!

[bzoj1895][Pku3580]supermemo_非旋转Treap的更多相关文章

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

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

  2. 关于非旋转treap的学习

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

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

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

  4. BZOJ5063旅游——非旋转treap

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. Program received signal SIGILL, Illegal instruction

    Program received signal SIGILL, Illegal instruction 这个错误,发现是直接在printf 的%s中直接使用string类型,而没有使用c字符串格式造成 ...

  2. 使用Kotlin,抛弃findViewById

    有没有觉得Android的findViewById挺烦人的.使用Kotlin可以让你彻底抛弃这个烦恼 步骤1.在build.gradle(Module:app)中添加如下一句话 这个在老一点版本的An ...

  3. UI动画效果

    UI界面的动画效果总结 方式1:头尾式 //开始动画 [UIView beginAnimations:nil context:nil]; //设置动画时间 [UIView setAnimationDu ...

  4. 到T-SQL DML 三级的阶梯:在SQL server中实现关系模型

    作者: Gregory Larsen, 2017/08/02 (第一次出版: 2011/11/09) 翻译:谢雪妮,许雅莉,赖慧芳,刘琼滨 译文: 系列 该文章是阶梯系列的一部分:T-SQL DML的 ...

  5. Farseer.net轻量级ORM开源框架 V1.x 入门篇:数据库上下文

    导航 目   录:Farseer.net轻量级ORM开源框架 目录 上一篇:Farseer.net轻量级ORM开源框架 V1.x 入门篇:数据库配置文件 下一篇:Farseer.net轻量级ORM开源 ...

  6. Swift 关键字 inout - 让值类型以引用方式传递

    两种参数传递方式 值类型 传递的是参数的一个副本,这样在调用参数的过程中不会影响原始数据. 引用类型 把参数本身引用(内存地址)传递过去,在调用的过程会影响原始数据. 在 Swift 众多数据类型中, ...

  7. python爬虫学习:分布式抓取

    前面的文章都是基于在单机操作,正常情况下,一台机器无论配置多么高,线程开得再多,也总会有一个上限,或者说成本过于巨大.因此,本文将提及分布式的爬虫,让爬虫的效率提高得更快. 构建分布式爬虫首先需要有多 ...

  8. HTTP请求报文与响应报文格式

    请求报文包含三部分: a.请求行:包含请求方法.URI.HTTP版本信息 b.请求首部字段 c.请求内容实体 响应报文包含三部分: a.状态行:包含HTTP版本.状态码.状态码的原因短语 b.响应首部 ...

  9. CAD参数绘制mcdbsolid对象(com接口)

    C#中实现代码说明: private void DrawSolid() { //绘McDbSolid对象 axMxDrawX1.AddLinetype("MLineType1", ...

  10. 03XML Schema Definition

    1. XML Schema Definition 1. XML Schema Definition XML Schema(XML Schema Definition,XSD)用于描述 XML 文档的结 ...