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.

 

你可能感兴趣的:(play)