【bzoj4864】[BeiJing 2017 Wc]神秘物质 Splay

原文地址:http://www.cnblogs.com/GXZlegend/p/6801631.html



题目描述

21ZZ 年,冬。

小诚退休以后, 不知为何重新燃起了对物理学的兴趣。 他从研究所借了些实验仪器,整天研究各种微观粒子。这一天, 小诚刚从研究所得到了一块奇异的陨石样本, 便迫不及待地开始观测。 在精密仪器的视野下,构成陨石的每个原子都无比清晰。 小诚发现, 这些原子排成若干列, 每一列的结构具有高度相似性。于是,他决定对单独一列原子进行测量和测试。被选中的这列共有 N 个顺序排列的原子。 最初, 第 i 个原子具有能量 Ei。 随着时间推移和人为测试, 这列原子在观测上会产生两种变化:

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

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

对于一列原子,小诚关心的是相邻一段中能量最大和能量最小的两个原子的能量差值,称为区间极差。 因此, 除了观测变化外,小诚还要经常统计这列原子的两类数据:

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

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

其中, 子区间指的是长度至少是 2 的子区间。

小诚坚信这项研究可以获得诺贝尔物理学奖。为了让小诚早日了结心愿,你能否帮助他实现上述的观测和测量呢?

输入

第一行, 两个整数 N, M, 分别表示最初的原子数目和事件总数。

第二行, N 个整数 E1, E2, …, EN, 由空格隔开。依次表示每个原子的能量。

接下来 M 行, 每行为一个字符串和两个整数, 描述一次事件,格式见题目描述。

N<=100,000,M<=100,000

1 ≤ e, Ei ≤ 109。 设 N’ 为当前时刻原子数目。

对于 merge 类事件, 1 ≤ x ≤ N’-1;

对于 insert 类事件, 1 ≤ x ≤ N’;

对于 max 和 min 类事件, 1 ≤ x < y ≤ N’。

任何时刻,保证 N’ ≥ 2。

输出

输出若干行, 按顺序依次表示每次 max 和 min 类事件的测量结果。

样例输入

4 3

5 8 10 2

max 1 3

min 1 3

max 2 4

样例输出

5
2
8



题解

Splay

支持插入删除修改查询操作的数据结构当然是Splay

而且有:极差最大值必为整个区间的极差,极差最小值必为区间内两个相邻数的差的绝对值。

所以Splay应维护:子树最大值、子树最小值、子树最小极差。

前两个操作很水,最后一个操作还需要用到左子树中最后一个数、右子树中第一个数,一起维护一下就好了。

1A~ 很开心~

#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 200010
using namespace std;
int fa[N] , c[2][N] , si[N] , w[N] , maxn[N] , minn[N] , dl[N] , dr[N] , ms[N] , root;
char str[10];
int abs(int x)
{
	return x > 0 ? x : -x;
}
void pushup(int x)
{
	si[x] = si[c[0][x]] + si[c[1][x]] + 1;
	dl[x] = c[0][x] ? dl[c[0][x]] : x;
	dr[x] = c[1][x] ? dr[c[1][x]] : x;
	maxn[x] = max(w[x] , max(maxn[c[0][x]] , maxn[c[1][x]]));
	minn[x] = min(w[x] , min(minn[c[0][x]] , minn[c[1][x]]));
	ms[x] = min(ms[c[0][x]] , ms[c[1][x]]);
	if(c[0][x]) ms[x] = min(ms[x] , abs(w[x] - w[dr[c[0][x]]]));
	if(c[1][x]) ms[x] = min(ms[x] , abs(w[x] - w[dl[c[1][x]]]));
}
void build(int l , int r , int f)
{
	if(l > r) return;
	int mid = (l + r) >> 1;
	build(l , mid - 1 , mid) , build(mid + 1 , r , mid);
	fa[mid] = f , c[mid > f][f] = mid;
	pushup(mid);
}
void rotate(int &k , int x)
{
	int y = fa[x] , z = fa[y] , l = (c[1][y] == x) , r = l ^ 1;
	if(y == k) k = x;
	else c[c[1][z] == y][z] = x;
	fa[x] = z , fa[y] = x , fa[c[r][x]] = y , c[l][y] = c[r][x] , c[r][x] = y;
	pushup(y) , pushup(x);
}
void splay(int &k , int x)
{
	while(x != k)
	{
		int y = fa[x] , z = fa[y];
		if(y != k)
		{
			if((c[0][z] == y) ^ (c[0][y] == x)) rotate(k , x);
			else rotate(k , y);
		}
		rotate(k , x);
	}
}
int find(int k , int x)
{
	if(x <= si[c[0][k]]) return find(c[0][k] , x);
	else if(x > si[c[0][k]] + 1) return find(c[1][k] , x - si[c[0][k]] - 1);
	else return k;
}
int split(int l , int r)
{
	int a = find(root , l - 1) , b = find(root , r + 1);
	splay(root , a) , splay(c[1][root] , b);
	return c[0][c[1][root]];
}
int main()
{
	int n , m , i , x , y , t , tot;
	scanf("%d%d" , &n , &m) , tot = n + 2;
	for(i = 2 ; i <= n + 1 ; i ++ ) scanf("%d" , &w[i]);
	maxn[0] = 0 , minn[0] = ms[0] = 0x3fffffff;
	build(1 , n + 2 , 0) , root = (n + 3) >> 1;
	while(m -- )
	{
		scanf("%s%d%d" , str , &x , &y);
		switch(str[1])
		{
			case ‘e‘: t = split(x + 1 , x + 2) , c[0][t] = c[1][t] = 0 , w[t] = y ,
			          pushup(t) , pushup(c[1][root]) , pushup(root); break;
			case ‘n‘: split(x + 2 , x + 1) , c[0][c[1][root]] = ++tot , w[tot] = y , fa[tot] = c[1][root] ,
			          pushup(tot) , pushup(c[1][root]) , pushup(root); break;
			case ‘a‘: t = split(x + 1 , y + 1) , printf("%d\n" , maxn[t] - minn[t]); break;
			default: printf("%d\n" , ms[split(x + 1 , y + 1)]);
		}
	}
	return 0;
}
时间: 2024-08-27 04:15:23

【bzoj4864】[BeiJing 2017 Wc]神秘物质 Splay的相关文章

bzoj4864: [BeiJing 2017 Wc]神秘物质

这道题维护区间极差的最小值 只有长度为二的区间有贡献 这个可以尝试画一下 自己想想 这样之后维护的值有 区间最小值 区间最大值 以及区间内长度为二的区间差的最小值 区间大小 点本身的值. 注意要看你维护的区间差在区间左点还是右点 这在查询min的时候很重要 剩下的自己看把 代码不算长的了 虽然有点慢 换成结构体应该会快很多 #include<cstdio> #include<cstring> #include<algorithm> using namespace std

#4864. [BeiJing 2017 Wc]神秘物质 [FHQ Treap]

这题其实挺简单的,有个东西可能稍微难维护了一点点.. \(merge\ x\ e\) 当前第 \(x\) 个原子和第 \(x+1\) 个原子合并,得到能量为 \(e\) 的新原子: \(insert\ x\ e\) 在当前第 \(x\) 个原子和第 \(x+1\) 个原子之间插入一个能量为 \(e\) 的新原子. \(max\ x\ y\) 当前第 \(x\) 到第 \(y\) 个原子之间的任意子区间中区间极差的最大值: \(min\ x\ y\) 当前第 \(x\) 到第 \(y\) 个原子之

【Foreign】神秘物质 [Splay]

神秘物质 Time Limit: 10 Sec  Memory Limit: 256 MB Description Input Output Sample Input Sample Output 1 2 1 5 HINT Main idea 每个点有一个权值,维护一个结构,支持合并相邻两点,删除单点,加入单点,查询区间子集极差的最大值和最小值. Solution 首先我们可以发现,区间子集极差的最大值显然就是整个区间的最大值-区间最小值,然后区间子集极差最小值只有相邻点的才会产生贡献. 那么我们

【bzoj4864】神秘物质

123 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 int n,m,a[200010]; 6 namespace splay{ 7 #define lson(x) t[x].lc 8 #define rson(x) t[x].rc 9 #define fa(x) t[x].fa 10 struct tree{ 11 int lc,rc,fa;

精子活力

二.引起精子活力低下的病因较多.归纳起来主要有以下几类是引起男子不育症的重要原因之一: 1.精索静脉曲张:由于精索静脉曲张导致毒性代谢产物CO2.类固醇.儿茶酚胺或前列腺素增多,到达睾丸而产生不良影响.同时睾丸局部瘀血,气血平衡失调,使精子形态及活动力受到影响. 2.生殖道感染:前列腺炎及精囊炎可影响到精液质量.其它如解脲支原体的感染及全身感染性疾病也可造成精子活力低下的发生. 3.理化因素的影响:药物.有机溶剂.烟酒.阴囊过热及环境污染,如:放射性.重金属.杀虫剂.化学毒物等,都可以引起精子活

学术会议高手速成之七种武器

学术江湖,虽无刀光剑影,却有血雨腥风.博士路上,漫漫修远,切磋技艺印证武功街头火拼胡同拍砖,大小战役,不可计数.一年数度之大型学术会议,更是群雄争锋之处华山论剑之时.回首五年江湖,西窗残阳似血,不胜唏嘘.暗观镜中博士帽上缨穗,犹感血迹斑斓,森然欲滴.遂决意退隐江湖葬剑青山,立志面朝大海春暖花开,再不过问学术界的是非恩怨.此五年心智武功,尽录于此,拳拳之心,皆为君故,诸位好生研习修炼,笑傲江湖之日,长歌烈酒,勿忘相邀.  第一种武器 长生剑 如果你想要一种最安全的武器闯荡江湖,你需要的是一把剑.连

中华神草新零售野山参的功效

野山参--凭什么被称作"神草"?野山参在2000多年前的<神农本草经>中就有记载,"主补五脏,安精神,定魂魄,止惊悸,除邪气,明目,开心益智,久服轻身延年",更在<本草纲目>中被李时珍称为"神草",而在现代生活中,野山参也会经常被用作补元气,安精神的良药.野山参不仅有补虚救脱.大补元气的功效,能强精健身益寿延年.服用野山参的好处:1.提高工作思维能力.减少疲劳野山参中皂苷 Rg1 能够兴奋中枢神经,加强大脑皮层的兴奋程度,

中斯间极积况意称天参并

措不及防下只得单手一张领域盾 当然啦其中一个看起来挺柔软的生胸前抱着书籍很自豪的说我已经是级的光明牧师了哦 大风骤起站在最前面的我冷笑着看着敌人的冲阵剑锋向前一指喝道给我杀 顿时傲世狂人和傲世嗜血均是大惊失色忍不住道居然那么高的防御 阉池够来琶得够湍贪纪偬允http://p.baidu.com/ihome/center?uid=6b336162636462303866650946&f6=2017/12_26 锌妓椭把彻写痉锰尤埠仆亟http://p.baidu.com/ihome/center?

Update:sparksql:第3节 Dataset (DataFrame) 的基础操作 &amp; 第4节 SparkSQL_聚合操作_连接操作

8. Dataset (DataFrame) 的基础操作 8.1. 有类型操作 8.2. 无类型转换 8.5. Column 对象 9. 缺失值处理 10. 聚合 11. 连接 8. Dataset (DataFrame) 的基础操作 导读 这一章节主要目的是介绍 Dataset 的基础操作, 当然, DataFrame 就是 Dataset, 所以这些操作大部分也适用于 DataFrame 有类型的转换操作 无类型的转换操作 基础 Action 空值如何处理 统计操作 8.1. 有类型操作 分