• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
L&King
有何不可!
   首页    新随笔    联系   管理    订阅  订阅

POJ 1754 Splay

单点更新,区间最值,用来练Splay刚好。

将位置作为排序的规则,利用Splay不会改变顺序的特点,求某一段区间[l,r]的最值时,将l-1伸展到根,将r+1伸展到l-1的右子树,这时r+1的左子树就是要求的区间。维护一个最值即可。

#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
const int N=200100,INF=0x3f3f3f3f;
int t[N][2],fa[N],id,root;
int data[N],res[N];
void pushup(int x){
    res[x]=max(res[t[x][0]],res[t[x][1]]);
    res[x]=max(data[x],res[x]);
}
inline void Rotate(int x,int w){//0:左旋    1:右旋 
    int y=fa[x];
    t[y][!w]=t[x][w];
    if(t[x][w])    fa[t[x][w]]=y;
    fa[x]=fa[y];
    if(fa[y])    t[fa[y]][t[fa[y]][1]==y]=x;
    t[x][w]=y;
    fa[y]=x;
    pushup(y);
    pushup(x);
}
void Splay(int x,int y){
    while(fa[x]!=y){
        if(t[fa[x]][0]==x)
            Rotate(x,1);
        else
            Rotate(x,0);
    }
    if(y==0)    root=x;
}
void newnode(int x,int v){
    t[x][0]=t[x][1]=0;
    fa[x]=x-1;
    res[x]=data[x]=v;
    t[x-1][1]=x;
}    
void updata(int x,int v){
    x++;
    data[x]=v;
    Splay(x,0);
    pushup(x);
}
int Q(int x,int y){
    y+=2;
    Splay(x,0);
    Splay(y,x);
    return res[t[y][0]];
}
int main(){
    char op[2];
    int x,v,n,m,i;
    while(scanf("%d%d",&n,&m)!=EOF){
        newnode(1,-INF);
        for(i=1;i<=n;i++){
            scanf("%d",&v);
            newnode(i+1,v);
        }
        newnode(n+2,-INF);
        for(i=n+2;i;i--)
            pushup(i);
        root=1;
        while(m--){
            scanf("%s%d%d",op,&x,&v);
            if(op[0]=='U')
                updata(x,v);
            else
                printf("%d\n",Q(x,v));
        }
    }
    return 0;
}

 

posted @ 2016-07-22 15:42  L&King  阅读(237)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3