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.

 

posted on 2013-12-08 17:15  BLADEVIL  阅读(410)  评论(0编辑  收藏  举报