bzoj 4864: [BeiJing 2017 Wc]神秘物质 (splay)
来源:互联网 发布:逻辑学悖论破解知乎 编辑:程序博客网 时间:2024/04/29 02:47
题目描述
传送门
题目大意:给出一个长度为n的序列
merge x e 将x,x+1合并,得到e
insert x e 在x,x+1之间插入 e
max x y 当前[x,y]中任意子区间中区间极差的最大值
min x y 当前[x,y]中任意子区间中区间极差的最小值
题解
这道题只要想清楚了min操作就是一个splay的裸题。
min中有贡献的子区间的长度只能是2,所以我们只要考虑相邻的两个数就可以了。
代码
#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<cmath>#define N 200003#define inf 2000000000using namespace std;int val[N],mx[N],mn[N],ck[N],gv[N],ch[N][2],fa[N],size[N],cnt,root;int n,m,a[N];void update(int now){ int l=ch[now][0]; int r=ch[now][1]; mx[now]=mn[now]=val[now]; ck[now]=gv[now]; size[now]=1; if (l) mx[now]=max(mx[now],mx[l]),mn[now]=min(mn[now],mn[l]), ck[now]=min(ck[now],ck[l]),size[now]+=size[l]; if (r) mx[now]=max(mx[now],mx[r]),mn[now]=min(mn[now],mn[r]), ck[now]=min(ck[now],ck[r]),size[now]+=size[r];}void clear(int x){ val[x]=mx[x]=mn[x]=ck[x]=gv[x]=ch[x][0]=ch[x][1]=0;}int build(int l,int r){ if (l>r) return 0; if (l==r) { int now=++cnt; val[now]=mx[now]=mn[now]=a[l]; size[now]=1; ck[now]=gv[now]=abs(a[l]-a[l-1]); return now; } int mid=(l+r)/2; int now=++cnt; val[now]=a[mid]; gv[now]=abs(a[mid]-a[mid-1]); ch[now][0]=build(l,mid-1); ch[now][1]=build(mid+1,r); fa[ch[now][0]]=fa[ch[now][1]]=now; update(now); return now;}int get(int x){ return ch[fa[x]][1]==x;}void rotate(int x){ int y=fa[x]; int z=fa[y]; int which=get(x); ch[y][which]=ch[x][which^1]; fa[ch[x][which^1]]=y; if (z) ch[z][ch[z][1]==y]=x; fa[x]=z; ch[x][which^1]=y; fa[y]=x; update(y); update(x);}void splay(int x,int tar){ for (int f;(f=fa[x])!=tar;rotate(x)) if (fa[f]!=tar) rotate(get(x)==get(f)?f:x); if (!tar) root=x;}int find(int x){ int now=root; while (true) { if (size[ch[now][0]]>=x) now=ch[now][0]; else { x-=size[ch[now][0]]; if (x==1) return now; x--; now=ch[now][1]; } }}int main(){ freopen("a.in","r",stdin); freopen("my.out","w",stdout); scanf("%d%d",&n,&m); a[1]=a[n+2]=inf; for (int i=1;i<=n;i++) scanf("%d",&a[i+1]); root=build(1,n+2); for (int i=1;i<=m;i++) { char s[10]; int x,y; scanf("%s%d%d",s+1,&x,&y); if (s[2]=='e') { int aa=find(x); int bb=find(x+3); splay(aa,0); splay(bb,aa); int t=ch[ch[root][1]][0]; clear(t); val[t]=mx[t]=mn[t]=y; size[t]=1; ck[t]=gv[t]=abs(val[root]-val[t]); gv[ch[root][1]]=abs(val[ch[root][1]]-val[t]); update(ch[root][1]); update(root); } if (s[2]=='i') { int aa=find(x+1); int bb=find(y+2); splay(aa,0); splay(bb,aa); int t=ch[ch[root][1]][0]; printf("%d\n",ck[t]); } if (s[2]=='a') { int aa=find(x); int bb=find(y+2); splay(aa,0); splay(bb,aa); int t=ch[ch[root][1]][0]; printf("%d\n",mx[t]-mn[t]); } if (s[1]=='i') { int aa=find(x+1); int bb=find(x+2); splay(aa,0); splay(bb,aa); int t=++cnt; fa[t]=ch[root][1]; ch[ch[root][1]][0]=cnt; val[t]=mx[t]=mn[t]=y; size[t]=1; ck[t]=gv[t]=abs(val[root]-val[t]); gv[ch[root][1]]=abs(val[ch[root][1]]-val[t]); update(ch[root][1]); update(root); } }}
0 0
- bzoj 4864: [BeiJing 2017 Wc]神秘物质 (splay)
- bzoj 4864: [BeiJing 2017 Wc]神秘物质 splay
- [BZOJ4864][BeiJing 2017 Wc]神秘物质(splay)
- 4864: [BeiJing 2017 Wc]神秘物质
- BZOJ4864 [BeiJing 2017 Wc]神秘物质
- splay jzoj4986 神秘物质
- [JZOJ4986] 神秘物质(splay模板)
- bzoj 2251: [2010Beijing Wc]外星联络 (后缀数组)
- [BZOJ 2252][2010Beijing wc]矩阵距离
- BZOJ 2251 [2010Beijing Wc]外星联络
- 【BZOJ】2252: [2010Beijing wc]矩阵距离
- BZOJ 2251 [2010Beijing Wc]外星联络
- bzoj 2251 [2010Beijing Wc]外星联络
- 神秘物质
- bzoj 2253: [2010 Beijing wc]纸箱堆叠 (CDQ分治+DP)
- BZOJ 2251: [2010Beijing Wc]外星联络|后缀数组
- BZOJ 2251 Beijing WC 2010 外星联络 后缀数组
- BZOJ 2251.[2010Beijing Wc]外星联络(Trie)
- 损失函数梯度对比-均方差和交叉熵
- eclipsese一些设置问题
- 简单实现LinkedList(双向链表)
- [C++]随机函数rand()和srand()的用法
- QT小知识点(2)
- bzoj 4864: [BeiJing 2017 Wc]神秘物质 (splay)
- stm32 PLL
- USACO 2017 January Contest, Gold Problem 2. Hoof, Paper, Scissors
- lintcode(640)Edit Distance
- 安卓中补间动画
- java泛型?解惑
- tftp 服务器搭建测试版本ubuntu14.04
- memset()初始化为1的那些事
- 删除大日志文件对系统负载的影响