【JSOI2007】动态最值 Splay
来源:互联网 发布:五笔for mac 编辑:程序博客网 时间:2024/05/18 20:04
题目描述
有一个包含n个元素的数组,要求实现以下操作:
DELETE k :删除位置k上的数。右边的数往左移一个位置。
QUERY i j :查询位置i~j上所有数的最小值和最大值。
例如有10个元素:
QUERY 2 8的结果为2 9。依次执行DELETE 3和DELETE 6(注意这时删除的是原始数组的元素7)后数组变为:
QUERY 2 8的结果为1 7。
题目大意
删数,求区间最大最小值。
数据范围
1≤n, m≤10^6 数字绝对值小于10^9
样例输入
10 4
1 5 2 6 7 4 9 3 1 5
2 2 8
1 3
1 6
2 2 8
样例输出
2 9
1 7
解题思路
Splay
代码
注意常数巨大,scanf都会超时一组。
#include <bits/stdc++.h>#define Maxn 1000005using namespace std;inline int Getint(){int x=0,f=1;char ch=getchar();while('0'>ch||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while('0'<=ch&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}int a[Maxn],n;struct splay{ int f[Maxn],son[Maxn][2],size[Maxn],vl[Maxn],Max[Maxn],Min[Maxn],root; void PushUp(int x){ if(!x)return; size[x]=size[son[x][0]]+size[son[x][1]]+1; Max[x]=max(max(Max[son[x][0]],Max[son[x][1]]),(x==1||x==n+2?-1<<30:vl[x])); Min[x]=min(min(Min[son[x][0]],Min[son[x][1]]),(x==1||x==n+2?1<<30:vl[x])); } void Rotate(int x){ int fa=f[x],gr=f[fa],s=son[fa][1]==x,sn=son[x][!s]; son[f[x]=gr][son[gr][1]==fa]=x; son[f[sn]=fa][s]=sn; son[f[fa]=x][!s]=fa; PushUp(sn); PushUp(fa); PushUp(x); } void Splay(int x,int goal){ if(x==goal)return; while(f[x]!=goal){ if(f[f[x]]!=goal&&(son[f[f[x]]][1]==f[x])==(son[f[x]][1]==x))Rotate(f[x]); Rotate(x); } if(!goal)root=x; } int Select(int pos){ if(!pos)return 0; int p=root; while(size[son[p][0]]+1!=pos){ if(pos<=size[son[p][0]])p=son[p][0]; else pos-=size[son[p][0]]+1,p=son[p][1]; } return p; } void Delete(int pos){ int u=Select(pos),v=Select(pos+2); Splay(u,0); Splay(v,u); size[son[v][0]]=0; f[son[v][0]]=0; son[v][0]=0; PushUp(v); PushUp(u); } void Build(int L,int r,int fa){ if(L>r)return; int mid=(L+r)/2; if(L==r){ Min[mid]=Max[mid]=vl[mid]=a[mid-1]; size[mid]=1; }else Build(L,mid-1,mid),Build(mid+1,r,mid); vl[mid]=a[mid-1]; f[mid]=fa; PushUp(mid); son[fa][mid>=fa]=mid; } void Solve(int L,int r){ int u=Select(L),v=Select(r+2); Splay(u,0); Splay(v,u); cout<<Min[son[v][0]]<<" "<<Max[son[v][0]]<<"\n"; } void Init(int n){ Min[n+1]=Min[0]=1<<30; Max[n+1]=Max[0]=-1<<30; Build(1,n+2,0); root=n+3>>1; }}Solver;int main(){ n=Getint(); int m=Getint(); for(int i=1;i<=n;i++)a[i]=Getint(); Solver.Init(n); while(m--){ int op=Getint(); if(op==1)Solver.Delete(Getint()); else{ int L=Getint(),r=Getint(); Solver.Solve(L,r); } } return 0;}
附我们学校OJ里超时的result
0 0
- 【JSOI2007】动态最值 Splay
- Splay解决区间问题[单点更新,区间最值询问]
- BZOJ 1552 浅谈SPLAY维护区间最值
- 【动态规划】【RQ225】【JSOI2007】书本整理
- BZOJ 1032 JSOI2007 祖码Zuma 动态规划
- hdu2475 Box splay || 动态树
- SPOJ OTOCI <动态树 + splay>
- splay 动态维护dfs序
- minmax动态最值
- bzoj 1027: [JSOI2007]合金(floyd最小环)
- bzoj 1030: [JSOI2007]文本生成器 AC自动机+动态规划
- HDU 1754 I Hate It (splay区间最值单点修改模板)
- 【线段树】动态最值
- Rank-Tree带动态查询删除 Splay
- SPLAY
- splay
- splay
- splay
- 读书笔记之--Java虚拟机精讲第六章内存分配与垃圾回收
- 一起学python(四)
- Delphi XE2 and C++ Builder XE2 Update4 HotFix1
- JUnit4单元测试报错问题 :method initializationerror not found
- 通用Adapter的实现套路(ListView篇)
- 【JSOI2007】动态最值 Splay
- poj3067 Japan 树状数组 逆序数
- 浅谈css中浮动和清除浮动带来的影响
- JVM入门
- 编程题
- 构建二叉树的两种方式(前+中) (中+后),递归
- CoordinatorLayout的使用
- 剑指Offer4:替换空格
- 如何在腾讯云上开发一款O2O书签?