當前位置:
首頁 >
前端技术
> javascript
>内容正文
javascript
【JSOI2007】动态最值 Splay
生活随笔
收集整理的這篇文章主要介紹了
【JSOI2007】动态最值 Splay
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目描述
有一個包含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 1000005 using 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
轉載于:https://www.cnblogs.com/Cedric341561/p/6811009.html
總結
以上是生活随笔為你收集整理的【JSOI2007】动态最值 Splay的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android程序员的进阶之路
- 下一篇: Oracle 数据表的管理