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.
  • 相关阅读:
    继续搞我的linux
    MySQL 开始
    我的小程序终于完工
    列表页 编辑页 删除页
    开发 记账小程序研发
    vue使用饿了么element-ui框架中的上传组件进度条无法使用,:on-progress钩子无法触发的原因
    移动端调试神器vConsole
    全栈高级web前端工程师的必经之路
    在vue中使用elementUI饿了么框架使用el-tabs,切换Tab如何实现实时加载,以及el-table表格使用总结
    GitBook的使用方式,快速创建网页文档
  • 原文地址:https://www.cnblogs.com/BLADEVIL/p/3458357.html
Copyright © 2011-2022 走看看