码迷,mamicode.com
首页 > 其他好文 > 详细

hdu1754splaytree区间查询

时间:2018-11-21 17:40:53      阅读:156      评论:0      收藏:0      [点我收藏+]

标签:bsp   splay   线段树   i++   区间   节点   int   key   date   

以前用线段树做的题。。发现splay好神奇

splay的区间查询就是把那个区间移到两个节点之间进行操作即可,同时每次rotate不要忘记pushup

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define maxn 200050

int pre[maxn],ch[maxn][2],size[maxn],Max[maxn],nums[maxn],keys[maxn],tot,root;
int a[maxn],n,q;

inline void pushup(int r){
    Max[r]=max(max(Max[ch[r][0]],Max[ch[r][1]]),keys[r]);
    size[r]=size[ch[r][0]]+size[ch[r][1]]+1;
}
inline void newnode(int &r,int fa,int val){
    r=++tot;
    ch[r][0]=ch[r][1]=0;
    size[r]=1;
    Max[r]=nums[r]=keys[r]=val;
    pre[r]=fa;
}
void build(int &r,int L,int R,int fa){
    if(L>R) return;
    int mid=L+R>>1;
    newnode(r,fa,a[mid]);
    build(ch[r][0],L,mid-1,r);
    build(ch[r][1],mid+1,R,r);
    pushup(r);
}
void init(){
    root=tot=0;
    ch[root][0]=ch[root][1]=size[root]=pre[root]=0;
    newnode(root,0,-1);newnode(ch[root][1],root,-1);
    build(ch[ch[root][1]][0],1,n,ch[root][1]);
    pushup(ch[root][1]);
    pushup(root);
}
void rotate(int x,int kind){
    int fa=pre[x];
    ch[fa][!kind]=ch[x][kind];
    pre[ch[x][kind]]=fa;
    pre[x]=pre[fa];
    if(pre[fa]) 
        ch[pre[fa]][ch[pre[fa]][1]==fa]=x;
    pre[fa]=x;
    ch[x][kind]=fa;
    pushup(fa);pushup(x);
}
void splay(int r,int goal){
    while(pre[r]!=goal){
        if(pre[pre[r]]==goal){
            rotate(r,ch[pre[r]][0]==r);
        }
        else {
            int fa=pre[r];
            int kind=ch[pre[fa]][0]==fa;
            if(ch[fa][kind]==r){
                rotate(r,!kind);
                rotate(r,kind);
            }
            else {
                rotate(fa,kind);
                rotate(r,kind);
            }
        }
    }
    pushup(r);
    if(goal==0) root=r;
}
int getth(int r,int pos){
    int t=size[ch[r][0]]+1;
    if(t==pos) return r;
    else if(t<pos) return getth(ch[r][1],pos-t);
    else return getth(ch[r][0],pos);
}
void update(int pos,int val){
    int r=getth(root,pos);
    splay(r,0);
    Max[root]=nums[root]=keys[root]=val;
    pushup(root);
}
int query(int l,int r){
    int L=getth(root,l),R=getth(root,r);
    splay(L,0);
    splay(R,root);
    return Max[ch[ch[root][1]][0]];
}
void Treavel(int x)
{
    if(x)
    {
        Treavel(ch[x][0]);
        printf("结点:%2d: 左儿子 %2d 右儿子 %2d 父结点 %2d size = %2d key = %2d\n",x,ch[x][0],ch[x][1],pre[x],size[x],keys[x]);
        Treavel(ch[x][1]);
    }
}
void debug()
{
    printf("root:%d\n",root);
    Treavel(root);
}
int main(){
    while(scanf("%d%d",&n,&q)==2){
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        init();
        
        int a,b;
        char op[5];
        while(q--){
            scanf("%s%d%d",&op,&a,&b);
            if(op[0]==U)
                update(a+1,b);
            else printf("%d\n",query(a,b+2));
        //debug();
        }
    }    
    return 0;
}

 

hdu1754splaytree区间查询

标签:bsp   splay   线段树   i++   区间   节点   int   key   date   

原文地址:https://www.cnblogs.com/zsben991126/p/9996011.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!