博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[bzoj4864][BeiJing 2017 Wc]神秘物质
阅读量:4618 次
发布时间:2019-06-09

本文共 2500 字,大约阅读时间需要 8 分钟。

来自FallDream的博客,未经允许,请勿转载,谢谢。


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<=10^5
 
话说省夏监考的时候写题真刺激..
这道题其实是一道平衡树裸题,max操作显然是问区间最大值和最小值,min操作只要稍微脑补一下都能发现答案只可能是相邻两个相差的绝对值的最小值
所以只要开两个splay,一个维护原数组,另一个维护差分数组即可
#include
#include
#define MN 200000using namespace std;inline int read(){ int x=0;char ch=getchar(); while(ch<'0'||ch>'9')ch=getchar(); while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar(); return x;}int n,m,a[MN+5],b[MN+5];inline int abs(int x){
return x<0?-x:x;}struct Splay{ int cnt,c[MN+5][2],fa[MN+5],size[MN+5],mx[MN+5],mn[MN+5],rt,s[MN+5]; void update(int x) { int l=c[x][0],r=c[x][1]; mx[x]=mn[x]=s[x];size[x]=size[l]+size[r]+1; if(l) mx[x]=max(mx[x],mx[l]),mn[x]=min(mn[x],mn[l]); if(r) mx[x]=max(mx[x],mx[r]),mn[x]=min(mn[x],mn[r]); } int build(int*a,int l,int r) { if(l>r)return 0; int mid=l+r>>1;s[mid]=a[mid]; c[mid][0]=build(a,l,mid-1);fa[c[mid][0]]=mid; c[mid][1]=build(a,mid+1,r);fa[c[mid][1]]=mid; update(mid); return mid; } void rotate(int x,int&k) { int y=fa[x],z=fa[y],l=c[y][1]==x,r=l^1; if(y==k) k=x; else c[z][c[z][1]==y]=x; fa[x]=z;fa[y]=x;fa[c[x][r]]=y; c[y][l]=c[x][r];c[x][r]=y; update(y);update(x); } void splay(int x,int&k) { for(;x!=k;rotate(x,k)) if(fa[x]!=k) rotate(c[fa[fa[x]]][1]==fa[x]^c[fa[x]][1]==x?x:fa[x],k); } int Find(int x,int rk) { int Sz=size[c[x][0]]+1; if(Sz==rk) return x; if(Sz>rk) return Find(c[x][0],rk); else return Find(c[x][1],rk-Sz); } int Split(int l,int r) { splay(Find(rt,l),rt); splay(Find(rt,r),c[rt][1]); return c[c[rt][1]][0]; } void Modify(int x,int rk,int v) { int Sz=size[c[x][0]]+1; if(Sz==rk){s[x]=v;update(x);return;} else if(Sz

转载于:https://www.cnblogs.com/FallDream/p/bzoj4864.html

你可能感兴趣的文章
父窗口与子窗口之间的传值
查看>>
eclipse 找不到 tomcat 的解决方案
查看>>
HDU 1890--Robotic Sort(Splay Tree)
查看>>
connection string for Excel/Access 2010
查看>>
【转】【Python】Python中的__init__.py与模块导入(from import 找不到模块的问题)
查看>>
学习wavenet_vocoder之环境配置
查看>>
常用Maven命令
查看>>
Docker启动mysql的坑2
查看>>
j2ee爬坑行之二 servlet
查看>>
JAVA基础入门(JDK、eclipse下载安装)
查看>>
最基础的applet运用--在applet上画线
查看>>
并不对劲的hdu4777
查看>>
linux使用rz、sz快速上传、下载文件
查看>>
判断数字的正则表达式
查看>>
DOC常用命令(转)
查看>>
php写一个判断是否有cookie的脚本
查看>>
Mac配置Fiddler抓包工具
查看>>
转:Java并发集合
查看>>
Word截图PNG,并压缩图片大小
查看>>
Python项目对接CAS方案
查看>>