zoukankan      html  css  js  c++  java
  • hdu1754splaytree区间查询

    以前用线段树做的题。。发现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
    ",x,ch[x][0],ch[x][1],pre[x],size[x],keys[x]);
            Treavel(ch[x][1]);
        }
    }
    void debug()
    {
        printf("root:%d
    ",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
    ",query(a,b+2));
            //debug();
            }
        }    
        return 0;
    }
  • 相关阅读:
    全屏透明遮罩层
    理解Javascript__理解undefined和null
    JS 对象属性相关--检查属性、枚举属性等
    js 空正则匹配任意一个位置
    a 标签 download 和 target 不配合
    Array.prototype.filter(Boolean)
    页面操作表单不会调用表单 value 属性的 set 函数
    Babel6.x的安装
    html 事件处理程序中的代码在执行时,有权访问全局作用域中的任何代码。
    js 常用 DOM 元素宽高
  • 原文地址:https://www.cnblogs.com/zsben991126/p/9996011.html
Copyright © 2011-2022 走看看