zoukankan      html  css  js  c++  java
  • bzoj 1251 裸splay

    裸的splay,只需要注意 max[-1]:=-maxlongint 就行了,否则在update的时候子节点的

    max值会在max[-1]里选

    /**************************************************************
        Problem: 1251
        User: BLADEVIL
        Language: Pascal
        Result: Accepted
        Time:16008 ms
        Memory:3448 kb
    ****************************************************************/
     
    //By BLADEVIL
    const
        sroot                   =-1;
    var
        n, m                    :longint;
        i                       :longint;
        a, father               :array[-1..100010] of longint;
        k, l, r, v              :longint;
        root                    :longint;
        max, size, tree         :array[-1..100010] of longint;
        val                     :array[-1..100010] of longint;
        flag                    :array[-1..100010] of boolean;
        son                     :array[-1..100010,0..1] of longint;
         
    procedure swap(var a,b:longint);
    var
        c                       :longint;
    begin
        c:=a; a:=b; b:=c;
    end;
         
    function get_max(a,b:longint):longint;
    begin
        if a>b then exit(a) else exit(b);
    end;
     
    procedure renew_add(x,v:longint);
    begin
        inc(tree[x],v); inc(val[x],v); inc(max[x],v);
    end;
     
    procedure renew_reverse(x:longint);
    begin
        swap(son[x,1],son[x,0]);
        flag[x]:=not flag[x];
    end;
         
    procedure update(x:longint);
    begin
        //if x=sroot then exit;
        max[x]:=get_max(tree[x],get_max(max[son[x,1]],max[son[x,0]]));
        size[x]:=size[son[x,1]]+size[son[x,0]]+1;
    end;
         
    function build(l,r:longint):longint;
    var
        mid                     :longint;
    begin
        mid:=(r+l) div 2;
        build:=mid;
        tree[mid]:=a[mid];
        if l+1<=mid then
        begin
            son[mid,0]:=build(l,mid-1);
            father[son[mid,0]]:=mid;
        end;
        if mid<=r-1 then
        begin
            son[mid,1]:=build(mid+1,r);
            father[son[mid,1]]:=mid;
        end;
        update(mid);
    end;
     
    procedure push_down(x:longint);
    var
        l, r                    :longint;
    begin
        l:=son[x,0]; r:=son[x,1];
        if flag[x] then
        begin
            if l<>-1 then renew_reverse(l);
            if r<>-1 then renew_reverse(r);
            flag[x]:=false;
        end;
        if val[x]<>0 then
        begin
            if l<>-1 then renew_add(l,val[x]);
            if r<>-1 then renew_add(r,val[x]);
            val[x]:=0;
        end;
    end;
         
    function find(x:longint):longint;
    var
        t                       :longint;
    begin
        t:=root;
        while true do
        begin
            push_down(t);
            if size[son[t,0]]+1=x then exit(t);
            if size[son[t,0]]+1>x then t:=son[t,0] else
            begin
                dec(x,size[son[t,0]]+1);
                t:=son[t,1];
            end;
        end;
    end;
     
    procedure rotate(x,y:longint);
    var
        f                       :longint;
    begin
        push_down(x);
        f:=father[x];
        father[son[x,y xor 1]]:=f;
        son[f,y]:=son[x,y xor 1];
        if f=root then root:=x else
            if f=son[father[f],0] then
                son[father[f],0]:=x else
                son[father[f],1]:=x;
        father[x]:=father[f];
        father[f]:=x;
        son[x,y xor 1]:=f;
        update(f);
        update(x);
    end;
     
    procedure splay(x,y:longint);
    var
        u, v                    :longint;
    begin
        while father[x]<>y do
        begin
            if father[father[x]]=y then
                rotate(x,ord(x=son[father[x],1])) else
            begin
                if son[father[x],0]=x then u:=1 else u:=-1;
                if son[father[father[x]],0]=father[x] then v:=1 else v:=-1;
                if u*v=1 then
                begin
                    rotate(father[x],ord(x=son[father[x],1]));
                    rotate(x,ord(x=son[father[x],1]));
                end else
                begin
                    rotate(x,ord(x=son[father[x],1]));
                    rotate(x,ord(x=son[father[x],1]));
                end;
            end;
        end;
        update(x);
    end;
         
    procedure add(l,r,v:longint);
    var
        p                       :longint;
    begin
        p:=find(l);splay(p,sroot);
        p:=find(r+2);splay(p,root);
        p:=son[son[root,1],0];
        renew_add(p,v);
    end;
     
    procedure reverse(l,r:longint);
    var
        p                       :longint;
    begin
        p:=find(l);splay(p,sroot);
        p:=find(r+2);splay(p,root);
        p:=son[son[root,1],0];
        renew_reverse(p);
    end;
     
    function ask_max(l,r:longint):longint;
    var
        p                       :longint;
    begin
        p:=find(l); splay(p,sroot);
        p:=find(r+2); splay(p,root);
        p:=son[son[root,1],0];
        ask_max:=max[p];
    end;
         
    begin
        fillchar(son,sizeof(son),255);
        read(n,m);
        max[-1]:=-maxlongint;
        for i:=1 to n do a[i]:=0;
        inc(n);
        root:=build(0,n);
        father[root]:=sroot;
        for i:=1 to m do
        begin
            read(k);
            if k=1 then
            begin
                read(l,r,v);
                add(l,r,v);
            end else
            begin
                read(l,r);
                if k=2 then    
                    reverse(l,r) else
                    writeln(ask_max(l,r));
            end;
        end;
    end.
  • 相关阅读:
    我要好offer之 二叉树大总结
    我要好offer之 字符串相关大总结
    楼层扔鸡蛋问题[转]
    Linux System Programming 学习笔记(十一) 时间
    Linux System Programming 学习笔记(十) 信号
    Linux System Programming 学习笔记(九) 内存管理
    Linux System Programming 学习笔记(八) 文件和目录管理
    Linux System Programming 学习笔记(七) 线程
    Linux System Programming 学习笔记(六) 进程调度
    APUE 学习笔记(十一) 网络IPC:套接字
  • 原文地址:https://www.cnblogs.com/BLADEVIL/p/3458357.html
Copyright © 2011-2022 走看看