zoukankan      html  css  js  c++  java
  • bzoj 1861 splay

    就是裸地splay,然后自己写的不是特别好,tle了,最近时间比较紧迫,有时间了改下,在此记录

    另附转载pascal AC代码最下面

    /**************************************************************
        Problem: 1861
        User: BLADEVIL
        Language: Pascal
        Result: Time_Limit_Exceed
    ****************************************************************/
     
    //By BLADEVIL
    const
        sroot                       =-1;
         
    var
        num, adress                 :array[-1..100100] of longint; 
        son                         :array[-1..100100,0..1] of longint;
        father, size, tree          :array[-1..100100] of longint;
        root                        :longint;
        n, m                        :longint;
         
    procedure init;
    var
        i                           :longint;
    begin
        read(n,m);
        for i:=1 to n do
        begin
            read(num[i]);
            adress[num[i]]:=i;
        end;
        readln;
    end;
     
    procedure update(x:longint);
    begin
        size[x]:=size[son[x,0]]+size[son[x,1]]+1;
    end;
     
    function find(x:longint):longint;
    var
        t                           :longint;
    begin
        t:=root;
        while true do
        begin
            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
        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
            if father[father[x]]=y then
                rotate(x,ord(x=son[father[x],1])) else
            begin
                if x=son[father[x],0] then u:=1 else u:=-1;
                if father[x]=son[father[father[x]],0] 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;
        update(x);
    end;
     
    function build(l,r:longint):longint;
    var
        mid                         :longint;
    begin
        mid:=(l+r) div 2;
        build:=mid;
        tree[mid]:=num[mid];
        if l<=mid-1 then
        begin
            son[mid,0]:=build(l,mid-1);
            father[son[mid,0]]:=mid;
        end;
        if r>=mid+1 then
        begin
            son[mid,1]:=build(mid+1,r);
            father[son[mid,1]]:=mid;
        end;
        update(mid);
    end;
     
    procedure top;
    var
        x                           :longint;
        q, p                        :longint;
    begin
        readln(x);
        x:=adress[x];
        splay(x,sroot);
        q:=size[son[root,0]];
        p:=find(q); splay(p,sroot);
        p:=find(q+2); splay(p,root);
        p:=son[son[root,1],0];
        son[son[root,1],0]:=-1;
        update(son[root,1]);
        update(root);
        father[p]:=-1;
        q:=find(2); splay(q,sroot);
        q:=find(1); splay(q,root);
        son[son[root,0],1]:=p;
        father[p]:=son[root,0];
        update(son[root,0]);
        update(root);
    end;    
     
    procedure bottom;
    var
        x                           :longint;
        q, p                        :longint;
    begin
        readln(x);
        x:=adress[x];
        splay(x,sroot);
        q:=size[son[x,0]];
        p:=find(q); splay(p,sroot);
        p:=find(q+2); splay(p,root);
        q:=son[son[root,1],0];
        son[son[root,1],0]:=-1;
        father[q]:=-1;
        update(son[root,1]);
        update(root);
        p:=find(n-1); splay(p,sroot);
        p:=find(n); splay(p,root);
        son[son[root,1],0]:=q;
        father[q]:=son[root,1];
        update(son[root,1]);
        update(root);
    end;
     
    procedure insert;
    var
        x, y                        :longint;
        q, p                        :longint;
         
    begin
        readln(x,y);
        x:=adress[x];
        if y=-1 then
        begin
            splay(x,sroot);
            p:=size[son[root,0]];
            q:=find(p); splay(q,sroot);
            q:=find(p+2); splay(q,root);
            x:=son[son[root,1],0];
            son[son[root,1],0]:=-1;
            q:=find(p-1); splay(q,sroot);
            q:=find(p); splay(q,root);
            son[son[root,1],0]:=x;
            father[x]:=son[son[root,1],0];
        end else
        begin
             
            splay(x,sroot);
            p:=size[son[root,0]];
            q:=find(p); splay(q,sroot);
            q:=find(p+2); splay(q,root);
            x:=son[son[root,1],0];
            son[son[root,1],0]:=-1;
            q:=find(p); splay(q,sroot);
            q:=find(p+2); splay(q,root);
            son[son[root,1],0]:=x;
            father[x]:=son[son[root,1],0];  
        end;
    end;
     
    procedure ask;
    var
        x                           :longint;
    begin
        readln(x);
        x:=adress[x];
        splay(x,sroot);
        writeln(size[son[root,0]]-1);
    end;
     
    procedure query;
    var
        x                           :longint;
        p                           :longint;
    begin
        readln(x);
        p:=find(x+1);
        splay(p,sroot);
        writeln(tree[root]);
    end;    
     
    procedure main;
    var
        i                           :longint;
        ch                          :char;
        s                           :ansistring;
         
    begin
        fillchar(son,sizeof(son),255);
        inc(n);
        root:=build(0,n);
        father[root]:=sroot;
        for i:=1 to m do
        begin
            s:='';
            read(ch);
            while ch<>' ' do
            begin
                s:=s+ch;
                read(ch);
            end;
            if s='Top' then top;
            if s='Bottom' then bottom;
            if s='Insert' then insert;
            if s='Ask' then ask;
            if s='Query' then query;
        end;
         
    end;
     
    begin
        init;
        main;
    end.
    /**************************************************************
        Problem: 1861
        User: BLADEVIL
        Language: Pascal
        Result: Accepted
        Time:2132 ms
        Memory:2140 kb
    ****************************************************************/
     
    {$inline on}
    program zjoi_2006_day2_book;
    var fa,pi,po,son:array[0..80000] of longint;
        c:array[0..80000,0..1] of longint;
        root,n,m:longint;
    //=====================================================================
    procedure rotate(var root:longint; x:longint); inline;
    var y,z,p,q:longint;
    begin
      y:=fa[x]; z:=fa[y];
      if c[y,0]=x then p:=0 else p:=1;
      q:=p xor 1;
      if y=root then root:=x else
        if c[z,0]=y then c[z,0]:=x else c[z,1]:=x;
      if c[x,q]>0 then fa[c[x,q]]:=y;
      fa[x]:=z; fa[y]:=x;
      c[y,p]:=c[x,q]; c[x,q]:=y;
      son[y]:=son[c[y,0]]+son[c[y,1]]+1;
      son[x]:=son[y]+son[c[x,p]]+1;    //一开始这里没加1
    end;
    //=====================================================================
    procedure splay(var root:longint; x:longint); inline;
    var y,z:longint;
    begin
      while x<>root do
      begin
        y:=fa[x]; z:=fa[y];
        if y<>root then
          if (c[y,0]=x) xor (c[z,0]=y) then
            rotate(root,x) else rotate(root,y);
        rotate(root,x);
      end;
    end; //经过多次实践,表示敲出splay和rotate的代码可以选择跳过调试了、、如果没有更新附加域的话。。
    //=====================================================================
    procedure init;
    var i,x:longint;
    begin
      readln(n,m);
      for i:=1 to n do
      begin
        read(x); pi[x]:=i;
        po[i]:=x; son[i]:=n-i+1;
      end; readln;    //这里没有readln的错误还是第一次碰到。。。
      for i:=1 to n-1 do c[i,1]:=i+1;
      for i:=1 to n do fa[i]:=i-1;
      root:=1; splay(root,n);
    end;
    //=====================================================================
    function delete(x:longint):longint; inline;
    var left,right:longint;
    begin
      splay(root,x);
      left:=c[root,0]; right:=c[root,1];
      while c[left,1]>0 do left:=c[left,1];
      while c[right,0]>0 do right:=c[right,0];
      if left>0 then splay(root,left);
      if right>0 then
        if left>0 then splay(c[root,1],right) else
          splay(root,right);
      if right=0 then
      begin delete:=n;
        c[left,1]:=0;
        if left>0 then dec(son[left]);
      end else
      begin
        if left>0 then
          delete:=son[left]-son[right]+1 else
            delete:=1;
        c[right,0]:=0; dec(son[right]);
        if left>0 then dec(son[left]);
      end; fa[x]:=0; son[x]:=1;
    end;
    //=====================================================================
    function find(x:longint):longint; inline;
    var i:longint;
    begin
      i:=root;
      while i<>0 do
      begin
        if son[c[i,0]]+1=x then exit(i);
        if son[c[i,0]]>=x then i:=c[i,0] else
        begin
          dec(x,son[c[i,0]]+1); i:=c[i,1];
        end;
      end; exit(i);
    end;
    //=====================================================================
    procedure ins(x,y:longint); inline;
    var left,right:longint;
    begin
      left:=find(y-1); right:=find(y);
      if left>0 then splay(root,left);
      if right>0 then
        if left>0 then splay(c[root,1],right) else
          splay(root,right);
      if right=0 then
      begin
        fa[x]:=left; c[left,1]:=x; inc(son[left]);
      end else
      begin
        inc(son[right]); fa[x]:=right; c[right,0]:=x;
        if left>0 then inc(son[left]);
      end;
    end;
    //=====================================================================
    procedure main;
    var ch,ch1:char;
        i,s,t,pos:longint;
    begin
      for i:=1 to m do
      begin
        repeat
          ch1:=ch; read(ch);
        until ch=' '; ch:=ch1; //如果init里面没有readln这里就会直接跳掉。读不到指令。然后就215了。。。
        if ch='p' then
        begin readln(s);
          pos:=delete(pi[s]); ins(pi[s],1);
        end else
        if ch='m' then
        begin readln(s);
          pos:=delete(pi[s]); ins(pi[s],n);
        end else
        if ch='t' then
        begin readln(s,t);
          if t=0 then continue;
          pos:=delete(pi[s]); ins(pi[s],pos+t);
        end else
        if ch='k' then
        begin readln(s);
          splay(root,pi[s]);
          writeln(son[c[root,0]]);
        end else
        begin readln(s);
          pos:=find(s); splay(root,pos);
          writeln(po[pos]);
        end;
      end;
    end;
    //=====================================================================
    begin
      //assign(input,'book.in'); reset(input);
      //assign(output,'book.out'); rewrite(output);
      init;
      main;
     // close(input); close(output);
    end.
  • 相关阅读:
    Microsoft Dynamics CRM2011 更换Logo
    Calling LoadLibraryEx on ISAPI filter failed
    Dynamics CRM2013/2015 插件注册工具登录后无法显示assembly列表问题的解决办法二
    python字符串
    python流程控制
    python反射
    python内置函数
    python集合
    python字符编码
    测试appstore地址
  • 原文地址:https://www.cnblogs.com/BLADEVIL/p/3464005.html
Copyright © 2011-2022 走看看