这题其实挺简单的,有个东西可能稍微难维护了一点点。。

\(merge\ x\ e\) 当前第 \(x\) 个原子和第 \(x+1\) 个原子合并,得到能量为 \(e\) 的新原子;

\(insert\ x\ e\) 在当前第 \(x\) 个原子和第 \(x+1\) 个原子之间插入一个能量为 \(e\) 的新原子。

\(max\ x\ y\) 当前第 \(x\) 到第 \(y\) 个原子之间的任意子区间中区间极差的最大值;

\(min\ x\ y\) 当前第 \(x\) 到第 \(y\) 个原子之间的任意子区间中区间极差的最小值。

极差最大值其实很显然是个区间 \(max - min\)

极差最小的区间呢,长度至少为 \(2\) 也必须为 \(2\)

至于证明的话

考虑 \(x,y,z\)

如果 \(x\) 和 \(z\) 的差的绝对值是解,那么 \(|x-y|\) 或者 \(|y-z|\) 一定更优

因为 \(x \leq y \leq z\) 才符合这种情况。

所以随便写写,把相邻两个的差变成后一个点的值,随便写写就可以了。

// by Isaunoya
#include <bits/stdc++.h>
using namespace std;
#define rep(i, x, y) for (register int i = (x); i <= (y); ++i)
#define Rep(i, x, y) for (register int i = (x); i >= (y); --i) const int _ = 1 << 21;
struct I {
char fin[_], *p1 = fin, *p2 = fin;
inline char gc() {
return (p1 == p2) && (p2 = (p1 = fin) + fread(fin, 1, _, stdin), p1 == p2) ? EOF : *p1++;
}
inline I& operator>>(int& x) {
bool sign = 1;
char c = 0;
while (c < 48) ((c = gc()) == 45) && (sign = 0);
x = (c & 15);
while ((c = gc()) > 47) x = (x << 1) + (x << 3) + (c & 15);
x = sign ? x : -x;
return *this;
}
inline I& operator>>(double& x) {
bool sign = 1;
char c = 0;
while (c < 48) ((c = gc()) == 45) && (sign = 0);
x = (c - 48);
while ((c = gc()) > 47) x = x * 10 + (c - 48);
if (c == '.') {
double d = 1.0;
while ((c = gc()) > 47) d = d * 0.1, x = x + (d * (c - 48));
}
x = sign ? x : -x;
return *this;
}
inline I& operator>>(char& x) {
do
x = gc();
while (isspace(x));
return *this;
}
inline I& operator>>(string& s) {
s = "";
char c = gc();
while (isspace(c)) c = gc();
while (!isspace(c) && c != EOF) s += c, c = gc();
return *this;
}
} in;
struct O {
char st[100], fout[_];
signed stk = 0, top = 0;
inline void flush() {
fwrite(fout, 1, top, stdout), fflush(stdout), top = 0;
}
inline O& operator<<(int x) {
if (top > (1 << 20)) flush();
if (x < 0) fout[top++] = 45, x = -x;
do
st[++stk] = x % 10 ^ 48, x /= 10;
while (x);
while (stk) fout[top++] = st[stk--];
return *this;
}
inline O& operator<<(char x) {
fout[top++] = x;
return *this;
}
inline O& operator<<(string s) {
if (top > (1 << 20)) flush();
for (char x : s) fout[top++] = x;
return *this;
}
} out;
#define pb emplace_back
#define fir first
#define sec second template < class T > inline void cmax(T & x , const T & y) {
(x < y) && (x = y) ;
}
template < class T > inline void cmin(T & x , const T & y) {
(x > y) && (x = y) ;
} int n , m , rt = 0 ;
const int N = 2e5 + 10 ;
int a[N] ;
const int inf = 0x7fffffff ;
int rnd[N] , val[N] , mx[N] , mn[N] , ch[N][2] , sz[N] ;
int cnt = 0 ;
#define ls(x) ch[x][0]
#define rs(x) ch[x][1]
int newnode(int v) {
++ cnt ;
val[cnt] = mx[cnt] = mn[cnt] = v ;
rnd[cnt] = rand() ;
sz[cnt] = 1 ;
return cnt ;
}
int t[N] , s[N] ;
void pushup(int rt) {
mx[rt] = mn[rt] = val[rt] ;
if(ls(rt)) cmin(mn[rt] , mn[ls(rt)]) , cmax(mx[rt] , mx[ls(rt)]) ;
if(rs(rt)) cmin(mn[rt] , mn[rs(rt)]) , cmax(mx[rt] , mx[rs(rt)]) ;
sz[rt] = sz[ls(rt)] + sz[rs(rt)] + 1 ;
t[rt] = min(t[ls(rt)] , t[rs(rt)]) , cmin(t[rt] , s[rt]) ;
}
int merge(int u , int v) {
if(! u || ! v) return u | v ;
if(rnd[u] < rnd[v]) {
rs(u) = merge(rs(u) , v) ;
pushup(u) ;
return u ;
} else {
ls(v) = merge(u , ls(v)) ;
pushup(v) ;
return v ;
}
}
void split(int cur , int k , int & u , int & v) {
if(! cur) {
u = v = 0 ;
return ;
}
if(k <= sz[ls(cur)]) {
v = cur ;
split(ls(v) , k , u , ls(v)) ;
} else {
u = cur ;
split(rs(u) , k - sz[ls(u)] - 1 , rs(u) , v) ;
}
pushup(cur) ;
}
void ins(int k , int v) {
int x , y , z , xx ;
split(rt , k - 1 , x , y) ;
split(y , 1 , y , z) ;
split(z , 1 , z , xx) ;
int now = newnode(v) ;
t[now] = s[now] = abs(val[now] - val[y]) ;
if(! y) {
t[now] = s[now] = inf ;
}
t[z] = s[z] = abs(val[z] - val[now]) ;
if(! z) {
t[z] = s[z] = inf ;
}
rt = merge(merge(merge(merge(x , y) , now) , z) , xx) ;
}
void _merge(int k , int v) {
int x , y , z , xx ;
split(rt , k - 1 , x , y) ;
split(y , 1 , y , z) ;
split(z , 1 , z , xx) ;
rt = merge(x , xx) ;
ins(k - 1 , v) ;
}
int qrymax(int l , int r) {
int x , y , z ;
split(rt , r , x , z) ;
split(x , l - 1 , x , y) ;
int res = mx[y] - mn[y] ;
rt = merge(merge(x , y) , z) ;
return res ;
}
int qrymin(int l , int r) {
++ l ;
int x , y , z ;
split(rt , r , x , z) ;
split(x , l - 1 , x , y) ;
int res = t[y] ;
rt = merge(merge(x , y) , z) ;
return res ;
}
void dfs(int u) {
if(ls(u)) dfs(ls(u)) ;
out << val[u] << '\n' ;
if(rs(u)) dfs(rs(u)) ;
}
signed main() {
#ifdef _WIN64
freopen("testdata.in" , "r" , stdin) ;
#endif
in >> n >> m ;
rep(i , 1 , n) in >> a[i] ;
rt = newnode(a[1]) ;
t[rt] = s[rt] = inf ;
rep(i , 2 , n) ins(i - 1 , a[i]) ;
rep(i , 1 , m) {
string s ;
in >> s ;
int x , y ;
in >> x >> y ;
if(s == "max") out << qrymax(x , y) << '\n' ;
if(s == "min") out << qrymin(x , y) << '\n' ;
if(s == "merge") _merge(x , y) ;
if(s == "insert") ins(x , y) ;
}
return out.flush(), 0;
}

#4864. [BeiJing 2017 Wc]神秘物质 [FHQ Treap]的更多相关文章

  1. BZOJ 4864: [BeiJing 2017 Wc]神秘物质 解题报告

    4864: [BeiJing 2017 Wc]神秘物质 Description 21ZZ 年,冬. 小诚退休以后, 不知为何重新燃起了对物理学的兴趣. 他从研究所借了些实验仪器,整天研究各种微观粒子. ...

  2. BZOJ 4864: [BeiJing 2017 Wc]神秘物质 (块状链表/平衡树 )

    这就是一道数据结构裸题啊,最大极差就是区间最大值减最小值,最小极差就是相邻两个数差的最小值.然后平衡树splay/treap或者块状链表维护就行了. 第一次自己写块状链表,蛮好写,就是长..然后就BZ ...

  3. BZOJ_4864_[BeiJing 2017 Wc]神秘物质_Splay

    BZOJ4864_[BeiJing 2017 Wc]神秘物质_Splay Description 21ZZ 年,冬. 小诚退休以后, 不知为何重新燃起了对物理学的兴趣. 他从研究所借了些实验仪器,整天 ...

  4. 【BZOJ4864】[BeiJing 2017 Wc]神秘物质 Splay

    [BZOJ4864][BeiJing 2017 Wc]神秘物质 Description 21ZZ 年,冬. 小诚退休以后, 不知为何重新燃起了对物理学的兴趣. 他从研究所借了些实验仪器,整天研究各种微 ...

  5. BZOJ4864[BeiJing 2017 Wc]神秘物质——非旋转treap

    题目描述 21ZZ 年,冬. 小诚退休以后, 不知为何重新燃起了对物理学的兴趣. 他从研究所借了些实验仪器,整天研究各种微观粒子.这 一天, 小诚刚从研究所得到了一块奇异的陨石样本, 便迫不及待地开始 ...

  6. [bzoj4864][BeiJing 2017 Wc]神秘物质

    来自FallDream的博客,未经允许,请勿转载,谢谢. 21ZZ 年,冬. 小诚退休以后, 不知为何重新燃起了对物理学的兴趣. 他从研究所借了些实验仪器,整天研究各种微观粒子.这 一天, 小诚刚从研 ...

  7. BZOJ4864 BeiJing 2017 Wc神秘物质(splay)

    splay维护区间最大值.最小值.相邻两数差的绝对值的最小值即可. #include<iostream> #include<cstdio> #include<cmath& ...

  8. BZOJ4864: [BeiJing 2017 Wc]神秘物质(Splay)

    Description 21ZZ 年,冬. 小诚退休以后, 不知为何重新燃起了对物理学的兴趣. 他从研究所借了些实验仪器,整天研究各种微观粒子.这 一天, 小诚刚从研究所得到了一块奇异的陨石样本, 便 ...

  9. [bzoj4864][BeiJing2017Wc]神秘物质_非旋转Treap

    神秘物质 bzoj-4864 BeiJing-2017-Wc 题目大意:给定一个长度为n的序列,支持插入,将相邻两个元素合并并在该位置生成一个指定权值的元素:查询:区间内的任意一段子区间的最大值减最小 ...

随机推荐

  1. Codeforces 1017D The Wu(状态压缩+预处理)

    题意: 给你n m q,表示在这一组数据中所有的01串长度均为n,然后给你一个含有m个元素的multiset,之后有q次询问.每次询问会给你一个01串t和一个给定常数k,让你输出串t和multiset ...

  2. python学习(3)关于交互输入及字符串拼接

    input是输入语句,用于人机交互. input() 函数接受一个标准输入数据,返回为 string 类型.如果需要输入的未数字,则需要额外定义. sex=input(“Sex:”) #这里会默认为S ...

  3. 用Java反射输出对象的所有属性的值

    获取对象的类类型 Class cls = obj.getClass(); 用类类型获取属性数组 getFields()获取的是共有属性 getDeclaredFields()可以获取所有属性 Fiel ...

  4. 并发编程之Master-Worker模式

    我们知道,单个线程计算是串行的,只有等上一个任务结束之后,才能执行下一个任务,所以执行效率是比较低的. 那么,如果用多线程执行任务,就可以在单位时间内执行更多的任务,而Master-Worker就是多 ...

  5. rabbitmq在kubernetes中持久化集群部署

    背景 Javashop电商系统的消息总线使用的事rabbitmq,在订单创建.静态页生成.索引生成等等业务中大量采用异步消息系统,这个对于mq高可用的要求有两个重要的考量: 1.集群化 2.可扩容 3 ...

  6. java连接Oracle数据库,从ResultSet中提取数据出现java.sql.sqlException结果集已耗尽

    出现错误的原因是ResultSet中并没有任何东西,再调用next()方法就会出错,原因可能是oracle创建用户,表没有提交,commit即可

  7. Spring-cloud微服务实战【九】:分布式配置中心config

      回忆一下,在前面的文章中,我们使用了spring cloud eureka/ribbon/feign/hystrix/zuul搭建了一个完整的微服务系统,不管是队内还是对外都已经比较完善了,那我们 ...

  8. Elasticsearch之集群

    ElasticSearch集群 ES集群是一个 P2P类型(使用 gossip 协议)的分布式系统,除了集群状态管理以外,其他所有的请求都可以发送到集群内任意一台节点上,这个节点可以自己找到需要转发给 ...

  9. C# 数据类型详解以及变量、对象与内存

    学习刘铁猛老师<C#语言入门详解>视频,针对其中重点知识点进行总结. 1.什么是类型? 类型又称为数据类型(Data Type),数据类型在数据结构中的定义是一个值的集合以及定义在这个值集 ...

  10. Blend 修改TreeViewItem样式

    Blend 修改TreeViewItem样式 1.用Blend for Visual Studio 2019 新建Wpf项目,拖动一个TreeView控件到Grid上 <Grid> < ...