1 条题解
-
0
自动搬运
来自洛谷,原作者为

cyffff
Not yet for the story on the last page, it's not the end.搬运于
2025-08-24 22:30:54,当前版本为作者最后更新于2021-05-30 20:36:06,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
在校内 看到的一道题,在 找到了,发现没有题解,于是来写一个。
sto zltzlt orz.
题意
给你一个序列 ,支持 个操作:
- ,删除结点 ,在 的位置插入一个节点,权值为 ;
- ,在 和 之间插入一个节点,权值为 ;
- ,查询区间 中任意子区间的区间极差的最大值;
- ,查询区间 中任意子区间的区间极差的最小值。
.
思路
看到插入、删除就可以想到使用文艺平衡树来解决问题,这里我使用 ,操作 十分显然。
操作可以直接维护区间的最大值和最小值,答案就是它们做差。
操作中,我们设答案的子区间为 ,设其中最大值为 ,最小值为 ,若区间中加入一个数 ,则 $a\gets \max(a,v),b\gets\min(b,v),\max(a,v)-\min(b,v)\ge a-b$,即插入一个数显然不会更优,所以答案区间长度为 。所以我们可以维护每个数与其左右的差的绝对值,分别设为 ,再维护 代表 子树内 的最小值,答案即为 。注意需要特判 的情况,直接取 。
代码:
#include<bits/stdc++.h> using namespace std; #define ll long long namespace IO{//by cyffff } const int N=5e5+10,INF=1e9+10; int s[N]; int n,m; struct Splay{ #define ls a[x].son[0] #define rs a[x].son[1] int rt,sz; struct node{ int f,val,son[2],sz; int minn=INF,maxn,lb,rb,ms; inline void clear(){ f=maxn=son[0]=son[1]=val=sz=0; minn=ms=lb=rb=INF; } }a[N]; inline bool isr(int x){return a[a[x].f].son[1]==x;} inline void upd(int x){ node &p=a[x]; p.maxn=p.minn=p.val; p.ms=min(p.lb,p.rb); if(ls) p.maxn=max(p.maxn,a[ls].maxn),p.minn=min(p.minn,a[ls].minn),p.ms=min(p.ms,a[ls].ms); if(rs) p.maxn=max(p.maxn,a[rs].maxn),p.minn=min(p.minn,a[rs].minn),p.ms=min(p.ms,a[rs].ms); p.sz=a[ls].sz+1+a[rs].sz; } inline int newnode(int v){ sz++; a[sz].minn=a[sz].maxn=a[sz].val=v; return sz; } inline void rotate(int x){ int f=a[x].f,gf=a[f].f; int id=isr(x); a[f].son[id]=a[x].son[id^1]; a[a[f].son[id]].f=f; a[x].son[id^1]=f; a[f].f=x; a[x].f=gf; if(gf){ a[gf].son[a[gf].son[1]==f]=x; } upd(f); } inline void splay(int x,int goal=0){ goal=a[goal].f; for(int f;(f=a[x].f)!=goal;rotate(x)){ if(a[f].f!=goal){ rotate(isr(x)==isr(f)?f:x); } } if(!goal) rt=x; } inline int build(int l,int r,int f){ if(l>r)return 0; int mid=l+r>>1; sz++; int now=sz; a[now].f=f; a[now].val=s[mid]; a[now].lb=mid?abs(s[mid]-s[mid-1]):INF; a[now].rb=mid!=n+1?abs(s[mid]-s[mid+1]):INF; a[now].son[0]=build(l,mid-1,now); a[now].son[1]=build(mid+1,r,now); upd(now); return now; } inline int find(int x){ int now=rt; while(1){ if(x<=a[a[now].son[0]].sz){ now=a[now].son[0]; }else{ x-=a[a[now].son[0]].sz+1; if(!x){ return now; } now=a[now].son[1]; } } } inline int split(int l,int r){ int x=find(l); splay(x,rt); int y=find(r+2); splay(y,a[x].son[1]); return a[y].son[0]; } inline void MoMerge(int wz,int v){ int x=split(wz,wz+1),f=rt,y=a[f].son[1]; a[x].val=v; if(ls) a[ls].clear(),ls=0; if(rs) a[rs].clear(),rs=0; a[f].rb=a[x].lb=abs(v-a[f].val); a[x].rb=a[y].lb=abs(v-a[y].val); upd(x),upd(y),upd(f); } inline void MoInsert(int wz,int v){ int x=split(wz,wz),f=rt,y=a[f].son[1],z=newnode(v); a[z].f=x; a[x].son[1]=z; a[x].rb=a[z].lb=abs(v-a[x].val); a[z].rb=a[y].lb=abs(v-a[y].val); upd(z),upd(x),upd(y); } inline int QuMax(int l,int r){ int x=split(l,r); return a[x].maxn-a[x].minn; } inline int QuMin(int l,int r){ int x; if(r-l<=1){ x=split(l,r-1); return a[x].rb; }else{ x=split(l+1,r-1); return a[x].ms; } } }t; int main(){ n=read(),m=read(); s[0]=INF; for(int i=1;i<=n;i++){ s[i]=read(); } s[n+1]=INF; t.sz=n+2; t.rt=t.build(0,n+1,0); while(m--){ char opt=getc(); switch(opt){ case 'e':{ int wz=read(),v=read(); t.MoMerge(wz,v); break; } case 'n':{ int wz=read(),v=read(); t.MoInsert(wz,v); break; } case 'a':{ int l=read(),r=read(); write(t.QuMax(l,r)); putc('\n'); break; } case 'i':{ int l=read(),r=read(); write(t.QuMin(l,r)); putc('\n'); break; } } } flush(); }再见 qwq~
- 1
信息
- ID
- 6633
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 5
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者