跳跃的小怪兽 Splay
来源:互联网 发布:手机sd数据恢复软件 编辑:程序博客网 时间:2024/04/29 13:00
题目描述
n个小怪兽站成一行跳来跳去。每次跳跃操作是以下两种形式之一:
a L b:从左到右第a个小怪兽跳过它左边的b个小怪兽,然后落地。
a D b:从左到右第a个小怪兽跳过它右边的b个小怪兽,然后落地。
小怪兽有身高差异,因此在跳跃时需要注意不要碰到其他小怪兽的头。具体来说,每次跳跃的高度等于越过的所有小怪兽的身高的最大值。
你的任务是计算出每次跳跃的高度。
题目大意
单点删除,单点插入,求区间最大值。
数据范围
n,j<=10000
样例输入
9 3
5 3 8 4 9 3 7 4 2
2 D 3
8 L 2
5 D 2
样例输出
9
7
4
解题思路
Splay维护区间,每个点有一个Max和vl属性,分别为当前区间最大值和当前点的值。
注意重新insert一个点后,这个点要设置Size为1,Max=vl。
代码
#include <algorithm>#include <iostream>#include <cstring>#include <cstdlib>#include <cstdio>#include <cmath>#define Maxn 200005using 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;}inline char Getch(){char ch=getchar();while(!isalpha(ch))ch=getchar();return ch;}int a[Maxn];struct splay{ int f[Maxn],son[Maxn][2],vl[Maxn],Max[Maxn],Size[Maxn],root,cnt; int GetSize(int x){ return Size[son[x][0]]+Size[son[x][1]]+1; } void PushUp(int x){ Max[x]=vl[x]; Max[x]=max(Max[son[x][0]],Max[x]); Max[x]=max(Max[son[x][1]],Max[x]); Size[x]=GetSize(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[fa]=x][!s]=fa; son[f[sn]=fa][s]=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 x){ if(!x)return 0; int p=root; while(Size[son[p][0]]+1!=x){ if(x<=Size[son[p][0]])p=son[p][0]; else x-=Size[son[p][0]]+1,p=son[p][1]; } PushUp(x); return p; } int Delete(int pos){ int u=Select(pos),v=Select(pos+2); Splay(u,0); Splay(v,u); f[son[v][0]]=0; int ret=vl[son[v][0]]; son[v][0]=0; Size[son[v][0]]=0; PushUp(v); PushUp(u); return ret; } void Insert(int pos,int val){ int u=Select(pos+1),v=Select(pos+2); Splay(u,0); Splay(v,u); vl[++cnt]=val; Max[cnt]=val; son[cnt][0]=son[cnt][1]=0; Size[cnt]=1; f[cnt]=v; son[v][0]=cnt; PushUp(v); PushUp(u); } int Ask(int L,int r){ int u=Select(L),v=Select(r+2); Splay(u,0); Splay(v,u); return Max[son[v][0]]; } void Build(int L,int r,int fa){ if(L>r)return; int mid=(L+r)/2; if(L==r){ Max[mid]=a[mid-1]; Size[mid]=1; son[mid][0]=son[mid][1]=0; } else Build(L,mid-1,mid),Build(mid+1,r,mid); f[mid]=fa; vl[mid]=a[mid-1]; PushUp(mid); son[fa][mid>=fa]=mid; }}Solver;int main(){ int n=Getint(),q=Getint(); for(int i=1;i<=n;i++)a[i]=Getint(); Solver.Build(1,n+2,0); Solver.root=n+3>>1; Solver.cnt=n+2; while(q--){ int pos=Getint(); char ch=Getch(); int Len=Getint(); if(ch=='L')cout<<Solver.Ask(pos-Len,pos-1)<<"\n"; if(ch=='D')cout<<Solver.Ask(pos+1,pos+Len)<<"\n"; int val=Solver.Delete(pos); if(ch=='D')Solver.Insert(pos+Len-1,val); if(ch=='L')Solver.Insert(pos-Len-1,val); } return 0;}
0 0
- 跳跃的小怪兽 Splay
- 奥特曼和小怪兽的故事
- 奥特曼打小怪兽(小怪兽)
- 奥特曼-小怪兽
- 小R打怪兽
- 怎么制作小怪兽打凹凸曼的游戏~
- 彩色小铅笔的跳跃与喘息
- Goop:滚吧,小怪兽
- 小怪兽日记(一)
- 小怪兽日记(二)
- 小怪兽日记(三)
- 小怪兽日记(四)
- 小怪兽日记(五)
- splay几个小模板
- 跳跃!跳跃!不断的跳跃!《Jump and Fly》的世界
- 从奥特曼和小怪兽的决斗中分析java类和对象-初学者必须会的一个入门程序
- Splay tree的splay操作
- 跳跃的幻想
- QT下,基于位置服务能力平台(LBS)的API测试
- iOS UIView正弦曲线切割
- PL/SQL Developer导入与导出数据库
- 分治法:给定平面上n个白点和n个黑点,试s合计一个分治算法江每个白点和黑点向量,所有连线互不相交
- java的 JSTL标签的使用
- 跳跃的小怪兽 Splay
- C++中stack的用法
- 实现点击输入框外的空白区域隐藏软键盘
- web前端之移动端适配
- linux文件权限
- Android:控件AutoCompleteTextView 和MultiAutoCompleteTextView的使用
- thyemleaf org.xml.sax.SAXParseException: 对实体 "*" 的引用必须以 ';' 分隔符结尾。
- C#ComboBox的联动
- docker初学三