[bzoj4864][BeiJing2017Wc]神秘物质_非旋转Treap
神秘物质 bzoj-4864 BeiJing-2017-Wc
题目大意:给定一个长度为n的序列,支持插入,将相邻两个元素合并并在该位置生成一个指定权值的元素;查询:区间内的任意一段子区间的最大值减最小值的最大值或最小值。
注释:$1\le n,m \le 10^5$,m为操作个数。
想法:如果用非旋转Treap的话,前两个操作就是傻逼操作。后两个操作也都比较简单:
1.如果是最大极差,我们就是将这个区间的最大值-最小值即可。
2.最小极差的话,显然只能是相邻两个数的差的绝对值的最小值,这东西也可以合并,那非旋转Treap维护一下即可。
最后,附上丑陋的代码... ...
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 102333
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
using namespace std;
const int inf=0x3fbbbbbb;
inline void read(int &x)
{
x=0;char c=getchar();
while(c<'0'||c>'9')c=getchar();
while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();
}
int n,m;
struct Node
{
int ls,rs,size,key,e,maxx,minn,minr,le,re;
}a[N<<1];
struct par{int x,y;};
inline void update(int x)
{
int ls=a[x].ls,rs=a[x].rs;
a[x].size=1,a[x].maxx=a[x].minn=a[x].le=a[x].re=a[x].e,a[x].minr=inf;
if(ls)
{
a[x].size+=a[ls].size;
a[x].maxx=max(a[x].maxx,a[ls].maxx);
a[x].minn=min(a[x].minn,a[ls].minn);
a[x].le=a[ls].le;
a[x].minr=min(a[x].minr,min(a[ls].minr,abs(a[ls].re-a[x].e)));
}
if(rs)
{
a[x].size+=a[rs].size;
a[x].maxx=max(a[x].maxx,a[rs].maxx);
a[x].minn=min(a[x].minn,a[rs].minn);
a[x].re=a[rs].re;
a[x].minr=min(a[x].minr,min(a[rs].minr,abs(a[rs].le-a[x].e)));
}
}
int merge(int x,int y)
{
if(!x||!y)return x|y;
if(a[x].key>a[y].key)
{
a[x].rs=merge(a[x].rs,y);update(x);
return x;
}
a[y].ls=merge(x,a[y].ls);update(y);
return y;
}
par split(int x,int k)
{
if(!k)return (par){0,x};
int ls=a[x].ls,rs=a[x].rs;
if(k==a[ls].size)
{
a[x].ls=0;update(x);
return (par){ls,x};
}
if(k==a[ls].size+1)
{
a[x].rs=0;update(x);
return (par){x,rs};
}
if(k<a[ls].size)
{
par t=split(ls,k);
a[x].ls=t.y;update(x);
return (par){t.x,x};
}
par t=split(rs,k-a[ls].size-1);
a[x].rs=t.x;update(x);
return (par){x,t.y};
}
int e[N],cnt,root;
inline int makenew(int val)
{
a[++cnt].size=1;
a[cnt].e=a[cnt].maxx=a[cnt].minn=a[cnt].le=a[cnt].re=val;
a[cnt].key=rand(),a[cnt].minr=inf;
return cnt;
}
int build(int l,int r)
{
if(l==r)return makenew(e[l]);
int mid=(l+r)>>1;
return merge(build(l,mid),build(mid+1,r));
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)read(e[i]);
root=build(1,n);
char s[10];
for(int x,y,i=1;i<=m;i++)
{
scanf("%s",s);
read(x);read(y);
if(s[1]=='e')
{
par t1=split(root,x+1),t2=split(t1.x,x-1);
root=merge(merge(t2.x,makenew(y)),t1.y);
}
else if(s[1]=='n')
{
par t=split(root,x);
root=merge(merge(t.x,makenew(y)),t.y);
}
else if(s[1]=='a')
{
par t1=split(root,y),t2=split(t1.x,x-1);
printf("%d\n",a[t2.y].maxx-a[t2.y].minn);
root=merge(merge(t2.x,t2.y),t1.y);
}
else if(s[1]=='i')
{
par t1=split(root,y),t2=split(t1.x,x-1);
printf("%d\n",a[t2.y].minr);
root=merge(merge(t2.x,t2.y),t1.y);
}
}
return 0;
}
小结:非旋转Treap真的是神一样的数据结构...
[bzoj4864][BeiJing2017Wc]神秘物质_非旋转Treap的更多相关文章
- [bzoj3173]最长上升子序列_非旋转Treap
最长上升子序列 bzoj-3173 题目大意:有1-n,n个数,第i次操作是将i加入到原有序列中制定的位置,后查询当前序列中最长上升子序列长度. 注释:1<=n<=10,000,开始序列为 ...
- [bzoj1500][NOI2005]维修数列_非旋转Treap
维修数列 bzoj-1500 NOI-2005 题目大意:给定n个数,m个操作,支持:在指定位置插入一段数:删除一个数:区间修改:区间翻转.查询:区间和:全局最大子序列. 注释:$1\le n_{ma ...
- [bzoj1552\bzoj2506][Cqoi2014]robotic sort 排序机械臂_非旋转Treap
robotic sort 排序机械臂 bzoj-1552 bzoj-2506 Cqoi-2014 题目大意:给定一个序列,让你从1到n,每次将[1,p[i]]这段区间反转,p[i]表示整个物品权值第i ...
- [bzoj1861][Zjoi2006]Book 书架_非旋转Treap
Book 书架 bzoj-1861 Zjoi-2006 题目大意:给你一个序列,支持:将指定编号的元素抽出,放到序列顶(底):将指定编号元素左右篡位:查询指定编号元素位置:查询指定数量位置元素编号. ...
- [BZOJ4864][BeiJing2017Wc]神秘物质(splay)
首先merge就是先delete两次再insert,Max就是整个区间的最大值减最小值,Min就是区间中所有相邻两数差的最小值. Splay支持区间最大值,区间最小值,区间相邻差最小值即可. #inc ...
- [bzoj3196][Tyvj1730]二逼平衡树_树套树_位置线段树套非旋转Treap/树状数组套主席树/权值线段树套位置线段树
二逼平衡树 bzoj-3196 Tyvj-1730 题目大意:请写出一个维护序列的数据结构支持:查询给定权值排名:查询区间k小值:单点修改:查询区间内定值前驱:查询区间内定值后继. 注释:$1\le ...
- BZOJ1500[NOI2005]维修数列——非旋转treap
题目描述 请写一个程序,要求维护一个数列,支持以下 6 种操作: 请注意,格式栏 中的下划线‘ _ ’表示实际输入文件中的空格 输入 输入的第1 行包含两个数N 和M(M ≤20 000),N 表示初 ...
- 关于非旋转treap的学习
非旋转treap的操作基于split和merge操作,其余操作和普通平衡树一样,复杂度保证方式与旋转treap差不多,都是基于一个随机的参数,这样构出的树树高为\(logn\) split 作用:将原 ...
- [Codeforces702F]T-Shirts——非旋转treap+贪心
题目链接: Codeforces702F 题目大意:有$n$种T恤,每种有一个价格$c_{i}$和品质$q_{i}$且每种数量无限.现在有$m$个人,第$i$个人有$v_{i}$元,每人每次会买他能买 ...
随机推荐
- C# Socket 您的主机中的软件中止了一个已建立的连接 An established connection was aborted by the software in your host machine
http://tieba.baidu.com/p/3223234493 问题: 服务端在接收客户端数据的时候,抛了个异常出来:System.Net.Sockets.SocketException: 您 ...
- P1228 地毯填补问题(分治)
P1228 地毯填补问题(分治) 题目描述 相传在一个古老的阿拉伯国家里,有一座宫殿.宫殿里有个四四方方的格子迷宫,国王选择驸马的方法非常特殊,也非常简单:公主就站在其中一个方格子上,只要谁能用地毯将 ...
- [python 基础]python装饰器(二)带参数的装饰器以及inspect.getcallargs分析
带参数的装饰器理解无非记住两点: 1.本质不过在基本的装饰器外面再封装一层带参数的函数 2.在使用装饰器语法糖的时候与普通装饰器不同,必须要加()调用,且()内的内容可以省略(当省略时,admin默认 ...
- go 条件语句if
一.if 语句 格式 if condition { // do something } 举例 package main import "fmt" func main(){ var ...
- Windows:Word,PPT,EXCEL com+组件配置
本文所涉及到配置前提: 服务器必须安装Office套件(Word,PPT,Excel) 第一部分 Word Com+组件权限配置 1.cmd模式输入dcomcnfg 2.找到Microsoft Wor ...
- POJ 2286 The Rotation Game IDA*
(再一次感谢学长幻灯片) ID A* 随便自己yy了一下. 额嗯 思路什么的都没有问题 就是改不对.. 无奈地删代码...边删边交. 删啊删 哎呦 AC了 ... ... ... 找删的那一段 . o ...
- Windows phone开发之文件夹与文件操作系列(一)文件夹与文件操作
Windows phone7中文件的存储模式是独立的,即独立存储空间(IsolatedStorage).对文件夹与文件操作,需要借助IsolatedStorageFile类. IsolatedStor ...
- 在C#程序中,创建、写入、读取XML文件的方法
一.在C#程序中,创建.写入.读取XML文件的方法 1.创建和读取XML文件的方法,Values为需要写入的值 private void WriteXML(string Values) { //保存的 ...
- CSS选择器优先级计算
优先级从高到低排列,浏览器优先满足前面的规则 1,!important优先级最高 2,内联样式 3,作者>读者>浏览器 4,优先级权重加法 id选择器+100/个 类/伪类选择器+10/个 ...
- Serializable资料整理
1. 序列化 简单的说就是为了保存 内存中各种对象的状态(是实例变量,不是方法),并且可以把保存的对象读取出来. 虽然保存 object states的方法很多,但是Java提供了一种保存对象状态的机 ...